home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BBS in a Box 3
/
BBS in a box - Trilogy III.iso
/
Files
/
Prog
/
B-C
/
C++Source Code Fmtr Folder
/
Src
/
ParserActions.cp
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
NeXTSTEP
RISC OS/Acorn
UTF-8
Wrap
Text File
|
1992-04-27
|
120.3 KB
|
3,651 lines
|
[
TEXT/MPS
]
#ifndef __PARSERACTIONS__
#include "ParserActions.h"
#endif
#ifndef __CSCANNER__
#include "CScanner.h"
#endif
#ifndef __FORMATTING__
#include "Formatting.h"
#endif
#ifndef __CDENT__
#include "cdent.h"
#endif
#ifndef __STRING__
#include <string.h>
#endif
#define DEBUGPARSER(proc, index) \
if (index >= 0 && (aParser->DebugFormatting() || aParser->DebugParser())) \
diag(kDebug, " # (" #proc ", %s) --> %d\n", aParser->NameOf(aToken->Type()), index);
#define DEBUGSETCONTEXT(proc) \
if (aParser->DebugFormatting()) \
diag(kDebug, " # " #proc "\n");
/*
** Global variables exported by ParserActions
*/
//ƒ-
PrsDeclList gPrsDeclList;
PrsId gPrsId;
PrsPlaceHolder gLexFlush(kSLex_Flush);
//ƒ+
/*
** Parsing class instances
*/
//ƒ-
static PrsStmtList gPrsStmtList;
static PrsStmt gPrsStmt;
static PrsDecl gPrsDecl;
static PrsDo gPrsDo;
static PrsIf gPrsIf;
static PrsFor gPrsFor;
static PrsElse gPrsElse;
static PrsStruct gPrsStruct;
static PrsSwitch gPrsSwitch;
static PrsWhile gPrsWhile;
static PrsExpr gPrsExpr;
static PrsNewLine gPrsNewLine;
static PrsNewLineIf gPrsNewLineIf;
//ƒ+
/*
** Lexical instances used as place holders on the parse stack
*/
//ƒ-
static PrsPlaceHolder gLexParsedId(kSLex_ParsedId);
static PrsPlaceHolder gLexDecl(kSLex_Decl);
static PrsPlaceHolder gPrsDeclType(kSPrs_DeclType);
static PrsPlaceHolder gLexRBrace(kSLex_RBrace, "]");
static PrsPlaceHolder gLexRCurly(kSLex_RCurly, "}");
static PrsPlaceHolder gLexLParen(kSLex_LParen, "(");
static PrsPlaceHolder gLexRParen(kSLex_RParen, ")");
static PrsPlaceHolder gLexCase(kSLex_Case, "case");
static PrsPlaceHolder gLexQuestion(kSLex_OpQuestion, "?");
static PrsPlaceHolder gLexBNot(kSLex_OpBNot, "~");
static PrsPlaceHolder gLexOpAssign(kSLex_OpAssign, "=");
static PrsPlaceHolder gLexSemiColon(kSLex_SemiColon, ";");
static PrsPlaceHolder gLexOperator(kSLex_ParsedId, "operator");
static PrsPlaceHolder gLexClassColon(kSLex_ClassColon, "::");
//ƒ+
/*
** Declare a token whose only purpose is to note that an OpenContext() has been
** done. When this token is dropped from the stack, a CloseContext() must
** also be done
*/
static PrsPlaceHolder gContext(kSLex_Context);
/*
** Context setting routines
*/
//µ setExprContext
#pragma segment ParserActions
static void setExprContext(register Formatting *aFormat)
{
aFormat->SetComma(gFS_expr1);
aFormat->SetLParen(gFS_expr5);
aFormat->SetRParen(gFS_expr7);
aFormat->SetName(gFS_expr8);
aFormat->SetOperator(gFS_expr4);
aFormat->SetAssign(gFS_expr6);
}
//µ setDeclContext
#pragma segment ParserActions
static void setDeclContext(register Formatting *aFormat)
{
aFormat->SetComma(gFS_decl1);
aFormat->SetLParen(gFS_decl3);
aFormat->SetRParen(gFS_decl11);
aFormat->SetName(gFS_expr8);
aFormat->SetOperator(gFS_expr4);
aFormat->SetAssign(gFS_expr6);
}
//µ setFundefContext
#pragma segment ParserActions
static void setFundefContext(register Formatting *aFormat)
{
aFormat->SetComma(gFS_fundef4);
aFormat->SetSemi(gFS_decl10);
aFormat->SetLCurly(gFS_fundef11);
aFormat->SetRCurly(gFS_fundef12);
aFormat->SetLParen(gFS_fundef3);
aFormat->SetRParen(gFS_fundef6);
aFormat->SetName(gFS_fundef2);
aFormat->SetOperator(gFS_expr4);
aFormat->SetAssign(gFS_expr6);
}
//µ setFuncallContext
#pragma segment ParserActions
static void setFuncallContext(register Formatting *aFormat)
{
aFormat->SetComma(gFS_funcall3);
aFormat->SetLParen(gFS_funcall2);
aFormat->SetRParen(gFS_funcall4);
}
/*µ inDerivationOf
** Return true if the current item is in the derivation of a particular
** Type()
*/
#pragma segment ParserActions
static Boolean inDerivationOf(const Parser *aParser, int aType)
{
int i = aParser->ItemIndex();
while (i > 0)
if (aParser->Pick(--i)->Type() == aType)
return (true);
return (false);
}
/*
** Parse methods
*/
/*µ kSPrs_Id (17)
** ( 0) ? ® • kSLex_Id -> ? kSLex_Id ® •
** ( 1) ? kSLex_Id ® • "::" -> ? kSLex_Id "::" ® •
** ( 2) ? kSLex_Id "::" ® • kSLex_Id -> ? • kSLex_ParsedId
** ( 3) ? kSLex_Id "::" ® • "~" -> ? kSLex_Id "::" "~" ® •
** ( 4) ? kSLex_Id "::" "~" ® • kSLex_Id -> ? • kSLex_ParsedId
** ( 5) ? kSLex_Id "::" "~" ® • ??? -> ? • kSLex_ParsedId ???
** ( 6) ? kSLex_Id "::" ® • ??? -> ? • kSLex_ParsedId ???
** (15) ? kSLex_Id ® • "::*" -> ? • kSLex_Id "::*" ® •
** (16) ? kSLex_Id "::*" ® • kSLex_Id -> ? • kSLex_ParsedId
** (17) ? KSLex_Id "::*" ® • ??? -> ? • kSLex_ParsedId "::*" ???
** ( 7) ? kSLex_Id ® • kSLex_Id -> ? • kSLex_ParsedId
** ( 8) ? kSLex_Id ® • ??? -> ? • kSLex_ParsedId ???
**
** ( 9) ? ® • "::" -> ? "::" ® •
** (10) ? "::" ® • kSLex_Id -> ? • kSLex_ParsedId
** (11) ? "::" ® • "~" -> ? "::" "~" ® •
** (12) ? "::" "~" ® • kSLex_Id -> ? • kSLex_ParsedId
** (13) ? "::" "~" ® • ??? -> ? • "::" "~" ???
** (14) ? "::" ® • ??? -> ? • "::" ???
**
** This class holds kSLex_Ids until such time as they can be recognized
** as being either fully or partially qualified names. Note that the only
** operator type of interest is "~". Hence, if aToken == kSLex_Op, we use
** aToken->MinorType(). Also in the "don't care" cases, check if aToken->Type()
** is kSLex_Flush. If so, we don't pass kSLex_Flush up the chain.
*/
#pragma segment ParserActions
Boolean
PrsId::Accept(Syntactic* aToken, Parser* aParser)
{
static const short handles[] =
{
//ƒ-
4, kSLex_Id, 4, kSLex_Id, kSLex_ClassColon, kSLex_Op, kSPrs_Id,
2, kSLex_Id, 3, kSLex_Id, kSLex_ClassColon, kSPrs_Id,
3, kSLex_OpBNot, 3, kSLex_Id, kSLex_ClassColon, kSPrs_Id,
12, kSLex_Id, 3, kSLex_ClassColon, kSLex_Op, kSPrs_Id,
16, kSLex_Id, 3, kSLex_Id, kSLex_Op, kSPrs_Id,
1, kSLex_ClassColon, 2, kSLex_Id, kSPrs_Id,
7, kSLex_Id, 2, kSLex_Id, kSPrs_Id,
10, kSLex_Id, 2, kSLex_ClassColon, kSPrs_Id,
11, kSLex_OpBNot, 2, kSLex_ClassColon, kSPrs_Id,
15, kSLex_OpClassStar, 2, kSLex_Id, kSPrs_Id,
0, kSLex_Id, 1, kSPrs_Id,
9, kSLex_ClassColon, 1, kSPrs_Id,
5, -1, 4, kSLex_Id, kSLex_ClassColon, kSLex_Op, kSPrs_Id,
6, -1, 3, kSLex_Id, kSLex_ClassColon, kSPrs_Id,
13, -1, 3, kSLex_ClassColon, kSLex_Op, kSPrs_Id,
17, -1, 3, kSLex_Id, kSLex_Op, kSPrs_Id,
8, -1, 2, kSLex_Id, kSPrs_Id,
14, -1, 2, kSLex_ClassColon, kSPrs_Id,
-1, -1, 0
//ƒ+
};
// Check for kSLex_Op, use MinorType() (? == kSLex_OpBNot, kSLex_OpClassStar)
short aType = aToken->Type();
if (aType == kSLex_Op)
aType = aToken->MinorType();
short anIndex = aParser->FindHandle(aType, handles);
switch (anIndex)
{
case 0: // ? ® • kSLex_Id -> ? kSLex_Id ® •
case 1: // ? kSLex_Id ® • "::" -> ? kSLex_Id "::" ® •
case 3: // ? kSLex_Id "::" ® • "~" -> ? kSLex_Id "::" "~" ® •
case 9: // ? ® • "::" -> ? "::" ® •
case 11: // ? "::" ® • "~" -> ? "::" "~" ® •
case 15: // ? kSLex_Id ® • "::*" -> ? • kSLex_Id "::*" ® •
aParser->TopItem(aToken);
aParser->Shift(this);
break;
case 2: // ? kSLex_Id "::" ® • kSLex_Id -> ? • kSLex_ParsedId
case 16: // ? kSLex_Id "::*" ® • kSLex_Id -> ? • kSLex_ParsedId
aParser->Reduce(new PrsId(aParser->Pick(2), aToken, aParser->Pick(1)), 3);
break;
case 4: // ? kSLex_Id "::" "~" ® • kSLex_Id -> ? • kSLex_ParsedId
aParser->Reduce(new PrsId(aParser->Pick(3), new PrsDestructor(aToken), aParser->Pick(2)), 4);
break;
case 5: // ? kSLex_Id "::" "~" ® • ??? -> ? • kSLex_ParsedId ???
aParser->Reduce(new PrsId(aParser->Pick(3), new PrsDestructor(0), aParser->Pick(2)), 4);
if (aToken->Type() != kSLex_Flush)
return (aParser->Parse(aToken));
break;
case 6: // ? kSLex_Id "::" ® • ??? -> ? • kSLex_ParsedId ???
aParser->Reduce(new PrsId(aParser->Pick(2), 0, aParser->Pick(1)), 3);
if (aToken->Type() != kSLex_Flush)
return (aParser->Parse(aToken));
break;
case 7: // ? kSLex_Id ® • kSLex_Id -> ? • kSLex_ParsedId ® kSLex_Id
case 8: // ? kSLex_Id ® • ??? -> ? • kSLex_ParsedId ???
{
Syntactic* anId = aParser->Pick(1);
anId->SexChange(kSLex_ParsedId);
aParser->Reduce(anId, 2);
if (aToken->Type() != kSLex_Flush)
return (aParser->Parse(aToken));
}
break;
case 10: // ? "::" ® • kSLex_Id -> ? • kSLex_ParsedId
aParser->Reduce(new PrsId(0, aToken, aParser->Pick(1)), 2);
break;
case 12: // ? "::" "~" ® • kSLex_Id -> ? • kSLex_ParsedId
aParser->Reduce(new PrsId(0, new PrsDestructor(aToken), aParser->Pick(2)), 3);
break;
case 13: // ? "::" "~" ® • ??? -> ? • "::" "~" ???
{
Syntactic* aClassOp = aParser->Pick(2);
Syntactic* aBitNotOp = aParser->Pick(1);
aParser->Reduce(aClassOp, 3);
aParser->Parse(aBitNotOp);
if (aToken->Type() != kSLex_Flush)
return (aParser->Parse(aToken));
}
break;
case 14: // ? "::" ® • ??? -> ? • "::" ???
aParser->Reduce(aParser->Pick(1), 2);
if (aToken->Type() != kSLex_Flush)
return (aParser->Parse(aToken));
break;
case 17: // ? KSLex_Id "::*" ® • ??? -> ? • kSLex_ParsedId "::*" ???
{
Syntactic* anId = aParser->Pick(2);
Syntactic* aClassOp = aParser->Pick(1);
anId->SexChange(kSLex_ParsedId);
aParser->Reduce(anId, 2);
aParser->Parse(aClassOp);
if (aToken->Type() != kSLex_Flush)
return (aParser->Parse(aToken));
}
break;
default:
return (false);
}
return (true);
}
/*µ kSPrs_StmtList (22)
** ( 0) ® • "(" -> ® kSPrs_Stmt • "("
** ( 1) ® • "[" -> ® kSPrs_Stmt • "["
** ( 2) ® • "break" -> ® kSPrs_Stmt • "break"
** ( 3) ® • ";" -> ® kSPrs_Stmt • ";"
** ( 4) ® • kSLex_Op -> ® kSPrs_Stmt • kSLex_Op
** ( 5) ® • kSLex_ParsedId -> ® kSPrs_Stmt • kSLex_ParsedId
** ( 6) ® • "do" -> ® kSPrs_Stmt • "do"
** ( 7) ® • "for" -> ® kSPrs_Stmt • "for"
** ( 8) ® • "if" -> ® kSPrs_Stmt • "if"
** ( 9) ® • "switch" -> ® kSPrs_Stmt • "switch"
** (10) ® • "while" -> ® kSPrs_Stmt • "while"
** (11) ® • "{" -> ® kSPrs_Stmt • "{"
** (12) ® • kSLex_Value -> ® kSPrs_Stmt • kSLex_Value
** (19) ® • kSLex_Op -> ® kSPrs_Stmt • kSLex_Op
** Do a normal statement
**
** (21) ® • "else" -> ® kSPrs_Else • "else"
** (22) ® • kSPrs_Else -> ® •
** "else" statements can be commented out by #ifdef and require
** formatting.
**
** (13) ® • "struct" -> ® kSPrs_Decl • "struct"
** (14) ® • kSLex_Decl -> ® kSPrs_Decl • kSLex_Decl
** (15) ® kSPrs_Decl • "," -> ® kSPrs_Decl • kSLex_Decl
** Do a declaration
**
** (16) ® • kSPrs_Stmt -> ® •
** (17) ® • kSPrs_Decl -> ® •
** Single statments are part of the statement list
**
** (18) ® kSPrs_Stmt • "}" -> ® • "}"
** (20) ® kSPrs_Decl • "}" -> ® • "}"
** Close the open statement.
*/
#pragma segment ParserActions
Boolean
PrsStmtList::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
15, kSLex_Comma, 2, kSPrs_StmtList, kSPrs_Decl,
18, kSLex_RCurly, 2, kSPrs_StmtList, kSPrs_Stmt,
20, kSLex_RCurly, 2, kSPrs_StmtList, kSPrs_Decl,
0, kSLex_LParen, 1, kSPrs_StmtList,
1, kSLex_LBrace, 1, kSPrs_StmtList,
2, kSLex_Break, 1, kSPrs_StmtList,
3, kSLex_SemiColon, 1, kSPrs_StmtList,
4, kSLex_Op, 1, kSPrs_StmtList,
5, kSLex_ParsedId, 1, kSPrs_StmtList,
6, kSLex_Do, 1, kSPrs_StmtList,
7, kSLex_For, 1, kSPrs_StmtList,
8, kSLex_If, 1, kSPrs_StmtList,
9, kSLex_Switch, 1, kSPrs_StmtList,
10, kSLex_While, 1, kSPrs_StmtList,
11, kSLex_LCurly, 1, kSPrs_StmtList,
12, kSLex_Value, 1, kSPrs_StmtList,
13, kSLex_Struct, 1, kSPrs_StmtList,
14, kSLex_Decl, 1, kSPrs_StmtList,
16, kSPrs_Stmt, 1, kSPrs_StmtList,
17, kSPrs_Decl, 1, kSPrs_StmtList,
19, kSLex_Op, 1, kSPrs_StmtList,
21, kSLex_Else, 1, kSPrs_StmtList,
22, kSPrs_Else, 1, kSPrs_StmtList,
-1, -1, 0
//ƒ+
};
short anIndex = aParser->FindHandle(aToken->Type(), handles);
DEBUGPARSER(StmtList, anIndex);
switch (anIndex)
{
case 0: // ® • "(" -> ® kSPrs_Stmt • "("
case 1: // ® • "[" -> ® kSPrs_Stmt • "["
case 2: // ® • "break" -> ® kSPrs_Stmt • "break"
case 3: // ® • ";" -> ® kSPrs_Stmt • ";"
case 4: // ® • kSLex_Op -> ® kSPrs_Stmt • kSLex_Op
case 5: // ® • kSLex_ParsedId -> ® kSPrs_Stmt • kSLex_ParsedId
case 6: // ® • "do" -> ® kSPrs_Stmt • "do"
case 7: // ® • "for" -> ® kSPrs_Stmt • "for"
case 8: // ® • "if" -> ® kSPrs_Stmt • "if"
case 9: // ® • "switch" -> ® kSPrs_Stmt • "switch"
case 10: // ® • "while" -> ® kSPrs_Stmt • "while"
case 11: // ® • "{" -> ® kSPrs_Stmt • "{"
case 12: // ® • kSLex_Value -> ® kSPrs_Stmt • kSLex_Value
case 19: // ® • kSLex_Op -> ® kSPrs_Stmt • kSLex_Op
aParser->Shift(&gPrsStmt);
return (aParser->Parse(aToken));
case 13: // ® • "struct" -> ® kSPrs_Decl • "struct"
case 14: // ® • kSLex_Decl -> ® kSPrs_Decl • kSLex_Decl
aParser->Shift(&gPrsDecl);
return (aParser->Parse(aToken));
case 15: // ® kSPrs_Decl • "," -> ® kSPrs_Decl • kSLex_Decl
aFormat->Comma();
aFormat->Display(aToken);
return (aParser->Parse(&gLexDecl));
case 16: // ® • kSPrs_Stmt -> ® •
case 17: // ® • KSPrs_Decl -> ® •
case 22: // ® • kSPrs_Else -> ® •
break;
case 18: // ® kSPrs_Stmt • "}" -> ® • "}"
case 20: // ® kSPrs_Decl • "}" -> ® • "}"
aParser->Drop(1);
return (Accept(aToken, aParser));
case 21: // ® • "else" -> ® kSPrs_Else • "else"
aParser->Shift(&gPrsElse);
return (aParser->Parse(aToken));
default:
if (aToken->IsSeparator())
{
aParser->GetFormatting()->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_DeclList (16)
** ( 0) ® • "struct" -> ® kSPrs_Decl • "struct"
** ( 1) ® • kSLex_ParsedId -> ® kSPrs_Decl • kSLex_ParsedId
** ( 2) ® • kSPrs_DeclType -> ® kSPrs_Decl • kSPrs_DeclType
** ( 3) ® • kSLex_Decl -> ® kSPrs_Decl • kSLex_Decl
** (10) ® • kSLex_Op -> ® kSPrs_Decl • kSLex_Op
** ( 4) ® • ";" -> ® •
** ( 5) ® • kSPrs_Decl -> ® •
** Almost anything is allowed to start a declaration. However, some
** are explicitly disallowed as being impossible.
**
** (11) ® • "}" -> ® •
** This is a very special case. Usually, "}" are not allowed. However,
** if this is the only item on the parse stack, then we allow it, because
** it might be the closing "}" of an 'extern "C"' declaration that was
** buried around conditional compilation clauses. If this is not the
** case, pass it along.
**
** ( 6) ® kSPrs_Decl • ";" -> ® • ";"
** ( 8) ® kSPrs_Decl • "}" -> ® • "}"
** ( 9) ® kSPrs_Decl • ")" -> ® • ")"
** A declaration is terminated by a closing quote.
**
** ( 7) ® kSPrs_Decl • "," -> ® kSPrs_Decl •
** A comma separates the components of a declaration. Keep parsing.
**
** (12) ® • "{" -> ® kSPrs_Stmt • "{"
** (13) ® • kSPrs_Stmt -> ® •
** More macro buffoonery. The function header was in a #ifdef, the
** body was outside the ifdef. Consequently, we erred. Fix it here
** by assuming that any open curly at this position is the body of
** a function whose header was eaten.
**
** (14) ? • kSLex_Public -> ? • kSLex_ParsedId
** Assume that the "public" keyword was not recognized because we are
** not parsing C++, we are parsing C. Cloak the keyword and try
** again. Do this only as a last resort (ItemIndex() == 0)
**
** (15) ? • "else" -> ? "else" kSPrs_Else • "else"
** (16) ? "else" • kSPrs_Else -> ? •
** Assume the "else" was commented out with a #ifdef. Parse the else,
** leaving a marker on the stack so that when the kSPrs_Else completes
** we know that it was this class that handled it.
*/
#pragma segment ParserActions
Boolean
PrsDeclList::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
6, kSLex_SemiColon, 2, kSPrs_DeclList, kSPrs_Decl,
7, kSLex_Comma, 2, kSPrs_DeclList, kSPrs_Decl,
8, kSLex_RCurly, 2, kSPrs_DeclList, kSPrs_Decl,
9, kSLex_RParen, 2, kSPrs_DeclList, kSPrs_Decl,
0, kSLex_Struct, 1, kSPrs_DeclList,
1, kSLex_ParsedId, 1, kSPrs_DeclList,
2, kSPrs_DeclType, 1, kSPrs_DeclList,
3, kSLex_Decl, 1, kSPrs_DeclList,
4, kSLex_SemiColon, 1, kSPrs_DeclList,
5, kSPrs_Decl, 1, kSPrs_DeclList,
10, kSLex_Op, 1, kSPrs_DeclList,
11, kSLex_RCurly, 1, kSPrs_DeclList,
12, kSLex_LCurly, 1, kSPrs_DeclList,
13, kSPrs_Stmt, 1, kSPrs_DeclList,
// 16, kSPrs_Else, 1, kSLex_Else,
14, kSLex_Public, 0,
// 15, kSLex_Else, 0,
-1, -1, 0
//ƒ+
};
short anIndex = aParser->FindHandle(aToken->Type(), handles);
DEBUGPARSER(DeclList, anIndex);
switch (anIndex)
{
case 0: // ® • "struct" -> ® kSPrs_Decl • "struct"
case 1: // ® • kSLex_ParsedId -> ® kSPrs_Decl • kSLex_ParsedId
case 2: // ® • kSPrs_DeclType -> ® kSPrs_Decl • kSPrs_DeclType
case 3: // ® • kSLex_Decl -> ® kSPrs_Decl • kSLex_Decl
case 10: // ® • kSLex_Op -> ® kSPrs_Decl • kSLex_Op
aParser->Shift(&gPrsDecl);
aParser->Parse(aToken);
break;
case 4: // ® • ";" -> ® •
aFormat->SetGlue(gFS_stmt1);
aFormat->Display(aToken);
break;
case 5: // ® • kSPrs_Decl -> ® •
case 13: // ® • kSPrs_Stmt -> ® •
break;
case 11: // ® • "}" -> ® •
// Only if this is the only one do we allow it
if (aParser->Depth() > 1)
return (false);
aFormat->SetGlue(gFS_decl9);
aFormat->Display(aToken);
break;
case 6: // ® kSPrs_Decl • ";" -> ® • ";"
aFormat->SetGlue(gFS_decl10);
aFormat->Display(aToken);
aParser->Drop(1);
break;
case 7: // ® kSPrs_Decl • "," -> ® kSPrs_Decl •
aFormat->Comma();
aFormat->Display(aToken);
break;
case 8: // ® kSPrs_Decl • "}" -> ® • "}"
case 9: // ® kSPrs_Decl • ")" -> ® • ")"
aParser->Drop(1);
return (Accept(aToken, aParser));
case 12: // ® • "{" -> ® kSPrs_Stmt • "{"
// Only if this is the only one we allow it
if (aParser->Depth() > 1)
return (false);
aParser->Shift(&gPrsStmt);
aParser->Parse(aToken);
break;
case 14: // ® • kSLex_Public -> • kSLex_ParsedId
if (aParser->ItemIndex() != 0)
return (false);
return (aParser->Parse(new PrsAsId(aToken)));
case 15: // ? • "else" -> ? "else" kSPrs_Else • "else"
aParser->Shift(aToken);
aParser->Shift(&gPrsElse);
aParser->Parse(aToken);
break;
case 16: // ? "else" • kSPrs_Else -> ? •
aParser->Drop(1);
break;
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_Stmt (36)
** ( 0) ® • "{" -> ® kSLex_Context kSPrs_StmtList •
** ( 1) ® kSLex_Context kSPrs_StmtList • "}" -> • kSPrs_Stmt
** Produce a statement list bracketed by "{" .. "}"
**
** ( 2) ® • ";" -> • kSPrs_Stmt
** Do the single semicolon sort of statement
**
** ( 3) ® • "do" -> kSPrs_Do • "do"
** ( 4) ® • "for" -> kSPrs_For • "for"
** ( 5) ® • "if" -> kSPrs_If • "if"
** ( 6) ® • "switch" -> kSPrs_Switch • "switch"
** ( 7) ® • "while" -> kSPrs_While • "while"
** (36) ® • "else" -> • kSPrs_Stmt "else"
** Switch on the keyword and call the proper parser
**
** ( 8) ® • kSLex_ParsedId -> ® kSLex_ParsedId •
** ( 9) ® kSLex_ParsedId • ":" -> ® •
** (10) ® kSLex_ParsedId • ??? -> ® kSLex_Context kSPrs_Expr • kSLex_ParsedId ???
** An identifier can be either an expression or a label. Defer until
** the ":" or something else is seen.
**
** (11) ® • "(" -> ® kSLex_Context kSPrs_Expr • "("
** (12) ® • "[" -> ® kSLex_Context kSPrs_Expr • "["
** (13) ® • kSLex_Value -> ® kSLex_Context kSPrs_Expr • kSLex_Value
** (14) ® • kSLex_Op -> ® kSLex_Context kSPrs_Expr • kSLex_Op
** (15) ® kSLex_Context kSPrs_Expr • ";" -> • kSPrs_Stmt
** (16) ® kSLex_Context kSPrs_Expr • kSPrs_Decl -> ® • kSPrs_Decl
** (17) ® kSLex_Context kSPrs_Expr • "," -> ® kSLex_Context kSPrs_Decl • kSLex_Decl
** (18) ® kSLex_Context kSPrs_Expr • "}" -> ® • "}"
** (19) ® kSLex_Context kSPrs_Expr • ??? -> ® • ???
** Parse an expression. The "," case could be a comma expression or it
** could be a declaration we thought was an expression. But we're a
** formatter, so we'll assume the usual case will be a declaration we
** thought was an expression, as most statements don't contain comma
** expressions outside parentheses.
**
** (20) ® • kSLex_Break -> ® •
** (21) ® • kSLex_Break -> ® kSLex_Break •
** (22) ® kSLex_Break • ";" -> • kSPrs_Stmt
** (23) ® kSLex_Break • ??? -> ® kSLex_Context kSPrs_Expr • ???
** Do a break or goto/return. The goto/return case has an optional
** expression following it.
**
** (24) ® • kSLex_Decl -> ® kSLex_Context kSPrs_Decl • kSLex_Decl
** (25) ® • "struct" -> ® kSLex_Context kSPrs_Decl • "struct"
** (26) ® kSLex_Context • kSPrs_Decl -> • kSPrs_Stmt
** (27) ® kSLex_Context kSPrs_Decl • "," -> ® kSLex_Context kSPrs_Decl •
** (28) ® kSLex_Context kSPrs_Decl • ??? -> ® • ???
** A declaration statement. Do it.
**
** (29) ® • "}" -> • kSPrs_Stmt "}"
** (30) ® kSLex_Context kSPrs_Expr • "do" -> • kSPrs_Stmt "do"
** (31) ® kSLex_Context kSPrs_Expr • "for" -> • kSPrs_Stmt "for"
** (32) ® kSLex_Context kSPrs_Expr • "if" -> • kSPrs_Stmt "if"
** (33) ® kSLex_Context kSPrs_Expr • "switch" -> • kSPrs_Stmt "switch"
** (34) ® kSLex_Context kSPrs_Expr • "while" -> • kSPrs_Stmt "while"
** (35) ® kSLex_Context kSPrs_Expr • "}" -> • "}"
** The statement did not terminate. Terminate the statement and the
** pass on the terminators. This sort of thing usually occurs from
** the use of macros which don't end in ";"
**
** Formatting.
** A context is opened whenever the stack shifts into the state
** "® kSPrs_Expr" and is closed whenever the kSPrs_Expr is removed.
** A context is also opened and closed around "{…}"
*/
#pragma segment ParserActions
Boolean
PrsStmt::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
1, kSLex_RCurly, 3, kSPrs_Stmt, kSLex_Context, kSPrs_StmtList,
15, kSLex_SemiColon, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Expr,
16, kSPrs_Decl, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Expr,
17, kSLex_Comma, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Expr,
18, kSLex_RCurly, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Expr,
27, kSLex_Comma, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Decl,
30, kSLex_Do, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Expr,
31, kSLex_For, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Expr,
32, kSLex_If, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Expr,
33, kSLex_Switch, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Expr,
34, kSLex_While, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Expr,
35, kSLex_RCurly, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Expr,
9, kSLex_Colon, 2, kSPrs_Stmt, kSLex_ParsedId,
22, kSLex_SemiColon, 2, kSPrs_Stmt, kSLex_Break,
26, kSPrs_Decl, 2, kSPrs_Stmt, kSLex_Context,
0, kSLex_LCurly, 1, kSPrs_Stmt,
2, kSLex_SemiColon, 1, kSPrs_Stmt,
3, kSLex_Do, 1, kSPrs_Stmt,
4, kSLex_For, 1, kSPrs_Stmt,
5, kSLex_If, 1, kSPrs_Stmt,
6, kSLex_Switch, 1, kSPrs_Stmt,
7, kSLex_While, 1, kSPrs_Stmt,
8, kSLex_ParsedId, 1, kSPrs_Stmt,
11, kSLex_LParen, 1, kSPrs_Stmt,
12, kSLex_LBrace, 1, kSPrs_Stmt,
13, kSLex_Value, 1, kSPrs_Stmt,
14, kSLex_Op, 1, kSPrs_Stmt,
20, kSLex_Break, 1, kSPrs_Stmt,
// 21, kSLex_Break, 1, kSPrs_Stmt,
24, kSLex_Decl, 1, kSPrs_Stmt,
25, kSLex_Struct, 1, kSPrs_Stmt,
29, kSLex_RCurly, 1, kSPrs_Stmt,
36, kSLex_Else, 1, kSPrs_Stmt,
19, -1, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Expr,
28, -1, 3, kSPrs_Stmt, kSLex_Context, kSPrs_Decl,
10, -1, 2, kSPrs_Stmt, kSLex_ParsedId,
23, -1, 2, kSPrs_Stmt, kSLex_Break,
-1, -1, 0
//ƒ+
};
/*
** Hack. State 21 is hidden under state 20. Discover if this is 20
*/
short anIndex = aParser->FindHandle(aToken->Type(), handles);
switch (anIndex)
{
case 20:
switch (aToken->MinorType())
{
case kSLex_BreakReturn:
case kSLex_BreakGoto:
anIndex = 21;
break;
}
}
DEBUGPARSER(Stmt, anIndex);
switch (anIndex)
{
case 0: // ® • "{" -> ® kSLex_Context kSPrs_StmtList •
aFormat->SetGlue(gFS_stmt0);
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aFormat->SetGlue(gFS_block1);
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(&gPrsStmtList);
break;
case 1: // ® kSLex_Context kSPrs_StmtList • "}" -> • kSPrs_Stmt
aFormat->SetGlue(gFS_block2);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Reduce(&gPrsStmt, 3);
break;
case 2: // ® • ";" -> • kSPrs_Stmt
aFormat->SetGlue(gFS_stmt0);
aFormat->SetGlue(gFS_stmt1);
aFormat->Display(aToken);
aParser->Reduce(&gPrsStmt, 1);
break;
case 3: // ® • "do" -> kSPrs_Do • "do"
aParser->TopItem(&gPrsDo);
aParser->Parse(aToken);
break;
case 4: // ® • "for" -> kSPrs_For • "for"
aParser->TopItem(&gPrsFor);
aParser->Parse(aToken);
break;
case 5: // ® • "if" -> kSPrs_If • "if"
aParser->TopItem(&gPrsIf);
aParser->Parse(aToken);
break;
case 6: // ® • "switch" -> kSPrs_Switch • "switch"
aParser->TopItem(&gPrsSwitch);
aParser->Parse(aToken);
break;
case 7: // ® • "while" -> kSPrs_While • "while"
aParser->TopItem(&gPrsWhile);
aParser->Parse(aToken);
break;
case 8: // ® • kSLex_ParsedId -> ® kSLex_ParsedId •
aParser->Shift(aToken);
break;
case 9: // ® kSLex_ParsedId • ":" -> ® •
aFormat->SetGlue(gFS_label1);
aFormat->Display(aParser->TopItem());
aFormat->Display(aToken);
aParser->Drop(1);
break;
case 10: // ® kSLex_ParsedId • ??? -> ® kSLex_Context kSPrs_Expr • kSLex_ParsedId ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
{
Syntactic* aName = aParser->TopItem();
aFormat->SetGlue(gFS_stmt0);
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aParser->TopItem(&gContext);
aParser->Shift(&gPrsExpr);
aParser->Parse(aName);
return (aParser->Parse(aToken));
}
case 11: // ® • "(" -> ® kSLex_Context kSPrs_Expr • "("
case 12: // ® • "[" -> ® kSLex_Context kSPrs_Expr • "["
case 13: // ® • kSLex_Value -> ® kSLex_Context kSPrs_Expr • kSLex_Value
case 14: // ® • kSLex_Op -> ® kSLex_Context kSPrs_Expr • kSLex_Op
aFormat->SetGlue(gFS_stmt0);
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aParser->Shift(&gContext);
aParser->Shift(&gPrsExpr);
aParser->Parse(aToken);
break;
case 15: // ® kSLex_Context kSPrs_Expr • ";" -> • kSPrs_Stmt
aFormat->SetGlue(gFS_stmt1);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Reduce(&gPrsStmt, 3);
break;
case 19: // ® kSLex_Context kSPrs_Expr • ??? -> ® • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
// !!! FALL THROUGH !!!
case 16: // ® kSLex_Context kSPrs_Expr • kSPrs_Decl -> ® • kSPrs_Decl
case 18: // ® kSLex_Context kSPrs_Expr • "}" -> ® • "}"
aFormat->CloseContext();
aParser->Drop(2);
return (Accept(aToken, aParser));
case 17: // ® kSLex_Context kSPrs_Expr • "," -> ® kSLex_Context kSPrs_Decl • kSLex_Decl
aFormat->Comma();
aFormat->Display(aToken);
aFormat->RestoreIndent();
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aParser->TopItem(&gPrsDecl);
aParser->Parse(&gLexDecl);
break;
case 27: // ® kSPrs_Decl • "," -> ® kSPrs_Decl •
aFormat->Comma();
aFormat->Display(aToken);
break;
case 20: // ® • kSLex_Break -> ® •
aFormat->SetGlue(gFS_break1);
aFormat->Display(aToken);
break;
case 21: // ® • kSLex_Break -> ® kSLex_Break •
aParser->Shift(aToken);
break;
case 22: // ® kSLex_Break • ";" -> • kSPrs_Stmt
aFormat->SetGlue(gFS_break1);
aFormat->Display(aParser->TopItem());
aFormat->SetGlue(gFS_stmt1);
aFormat->Display(aToken);
aParser->Reduce(this, 2);
break;
case 23: // ® kSLex_Break • ??? -> ® kSLex_Context kSPrs_Expr • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->SetGlue(aParser->TopItem()->MinorType() == kSLex_BreakGoto ? gFS_goto1 : gFS_return1);
aFormat->Display(aParser->TopItem());
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aParser->TopItem(&gContext);
aParser->Shift(&gPrsExpr);
aParser->Parse(aToken);
break;
case 24: // ® • kSLex_Decl -> ® kSLex_Context kSPrs_Decl • kSLex_Decl
case 25: // ® • "struct" -> ® kSLex_Context kSPrs_Decl • "struct"
aFormat->OpenContext();
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aParser->Shift(&gContext);
aParser->Shift(&gPrsDecl);
aParser->Parse(aToken);
break;
case 26: // ® kSLex_Context • kSPrs_Decl -> • kSPrs_Stmt
aFormat->CloseContext();
aParser->Reduce(this, 2);
break;
case 28: // ® kSLex_Context kSPrs_Decl • ??? -> ® • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->CloseContext();
aParser->Drop(2);
return (Accept(aToken, aParser));
case 29: // ® • "}" -> • kSPrs_Stmt "}"
aParser->Reduce(&gPrsStmt, 1);
return (aParser->Parse(aToken));
case 30: // ® kSLex_Context kSPrs_Expr • "do" -> • kSPrs_Stmt "do"
case 31: // ® kSLex_Context kSPrs_Expr • "for" -> • kSPrs_Stmt "for"
case 32: // ® kSLex_Context kSPrs_Expr • "if" -> • kSPrs_Stmt "if"
case 33: // ® kSLex_Context kSPrs_Expr • "switch" -> • kSPrs_Stmt "switch"
case 34: // ® kSLex_Context kSPrs_Expr • "while" -> • kSPrs_Stmt "while"
aFormat->CloseContext();
aParser->Reduce(this, 3);
return (aParser->Parse(aToken));
case 35: // ® kSLex_Context kSPrs_Expr • "}" -> • "}"
aFormat->CloseContext();
aParser->Drop(3);
return (Accept(aToken, aParser));
case 36: // ® • "else" -> • kSPrs_Stmt "else"
aParser->Reduce(this, 1);
return (aParser->Parse(aToken));
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_Decl (76)
** ( 0) ® • ";" -> • kSPrs_Decl
** An empty declaration, either a statement or just part of one
**
** ( 1) ® • kSPrs_Decl -> • kSPrs_Decl
** A parse is completed, probably by a "struct" declaration.
**
** ( 2) ® • "struct" -> ® kSLex_Context kSLex_Decl kSPrs_Struct • "struct"
** A structure declaration begins with the structure word. When done, it
** yields a kSPrs_Decl (if a complete declaration) or a kSPrs_DeclType.
**
** ( 3) ® • kSLex_ParsedId -> ® kSLex_Context kSLex_Decl •
** ( 4) ® • kSLex_Decl -> ® kSLex_Context kSLex_Decl •
** (76) ® • kSLex_Ellipsis -> ® kSLex_Context kSLex_Decl •
** An identifier here is treated the same as a type word. They both
** indicate that at least one type word has been found.
**
** ( 5) ® • kSLex_Op -> ® kSLex_Context kSLex_Decl •
** (52) ® • kSLex_OpBNot -> ® kSLex_OpBNot •
** ( 6) ® kSLex_OpBNot • kSLex_ParsedId -> ® kSLex_Context kSLex_Decl kSLex_ParsedId •
** (14) ® kSLex_OpBNot • ??? -> ® kSLex_Context kSLex_Decl • ???
** Recognize a destructor name. If the item following the "~" is not something
** we recognize, reduce and feed it directly to ourself. If the operator is
** not a "~", we assume we are in a declaration and try again.
**
**
** (74) ® • kSLex_Value -> ® kSLex_Context kSPrs_Expr • kSLex_Value
** (75) ® kSLex_Context kSPrs_Expr • ??? -> ® kSLex_Context kSLex_Decl • ???
** Alright, so it isn't just a list of declarations. It has a value in it.
** Parse the expression beginning with the value. When the expression
** completes, get rid of it and reduce to the "® kSLex_Context kSLex_Decl"
** state.
**
**
** The common state for a completed declaration is
** ® kSLex_Context kSLex_Decl
** indicating that at least one piece of the declaration has been parsed.
** When in this state, a ";", "}" or ")" will yield a declaration.
**
** ( 7) ® kSLex_Context kSLex_Decl • ";" -> ® • kSPrs_Decl
** ( 8) ® kSLex_Context kSLex_Decl • "," -> ® • ","
** ( 9) ® kSLex_Context kSLex_Decl • ")" -> ® • ")"
** (69) ® kSLex_Context kSLex_Decl • "}" -> ® • "}"
** End of a declaration. Pass it along.
**
**
** (10) ® kSLex_Context kSLex_Decl • kSPrs_DeclType -> ® kSLex_Context kSLex_Decl •
** (11) ® kSLex_Context kSLex_Decl • kSLex_Decl -> ® kSLex_Context kSLex_Decl •
** (12) ® kSLex_Context kSLex_Decl • kSPrs_Decl -> ® • kSPrs_Decl
** (15) ® kSLex_Context kSLex_Decl • "struct" -> ® • "struct"
** Two or more declaration words in a row collapse into one. kSPrs_DeclType
** is produced when a structure declaration is recognized. kSPrs_Decl is
** produced when the entire declaration is recognized by the "struct".
**
**
** The state noted as
** ® kSLex_Context kSLex_Decl kSLex_ParsedId •
** occurs when a declaration has been seen the object being declared has
** been seen. The kSLex_ParsedId is shifted onto the stack *but is not displayed*
** until more information has been passed in and we can decide how to display
** the item.
**
**
** (13) ® kSLex_Context kSLex_Decl • kSLex_ParsedId -> ® kSLex_Context kSLex_Decl kSLex_ParsedId •
** The identifier might be the name of a type or it might be what is
** being declared.
**
**
** (16) ® kSLex_Context kSLex_Decl • "{" -> ® kSLex_Context kSLex_Decl "(" ")" • "{"
** Assume that kSLex_Decl was a function header and that the body of the
** function follows.
**
**
** (17) ® kSLex_Context kSLex_Decl • "(" -> ® kSLex_Context kSLex_Decl "(" kSLex_Context kSPrs_Decl •
** Parse the argument list of a function declaration.
**
**
** (18) ® kSLex_Context kSLex_Decl "(" kSLex_Context kSPrs_Decl • ")" -> ® kSLex_Context kSLex_Decl "(" ")" •
** (19) ® kSLex_Context kSLex_Decl "(" kSLex_Context kSPrs_Decl • "," -> ® kSLex_Context kSLex_Decl "(" kSPrs_Decl •
** Reduce a topmost parenthesized expression to a function header. The
** function header can then be followed by constructor initializers
** (such as :BaseClass() ,field(value) {initStmt;})
**
**
** (20) ® kSLex_Context kSLex_Decl "(" ")" • "const -> ® kSLex_Context kSLex_Decl "(" ")" •
** (21) ® kSLex_Context kSLex_Decl "(" ")" • "volatile" -> ® kSLex_Context kSLex_Decl "(" ")" •
** (22) ® kSLex_Context kSLex_Decl "(" ")" • kSLex_Op -> ® kSLex_Context kSLex_Decl • kSLex_Op
** (23) ® kSLex_Context kSLex_Decl "(" ")" • ";" -> ® kSLex_Context kSLex_Decl • ";"
** (24) ® kSLex_Context kSLex_Decl "(" ")" • "," -> ® kSLex_Context kSLex_Decl • ","
** (25) ® kSLex_Context kSLex_Decl "(" ")" • "{" -> ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context "{" kSPrs_StmtList •
** (26) ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context "{" kSPrs_StmtList • "}" -> • kSPrs_Decl
** After the header has been parsed, parse the body. This handles function
** prototypes. A "® kSLex_Context kSLex_Decl "(" ")" "{" kSPrs_DeclList •"
** is left on the stack while parsing the body of the function. When the "}"
** comes, we have a declaration and reduce to one.
**
**
** (27) ® kSLex_Context kSLex_Decl "(" ")" • kSLex_Decl -> ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context kSPrs_DeclList • kSLex_Decl
** (27) ® kSLex_Context kSLex_Decl "(" ")" • "struct" -> ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context kSPrs_DeclList • "struct"
** (28) ® kSLex_Context kSLex_Decl "(" ")" • kSLex_ParsedId -> ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context kSPrs_DeclList • kSLex_ParsedId
** (29) ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context kSPrs_DeclList • "{" -> ® kSLex_Context kSLex_Decl "(" ")" • "{"
** This handles "old-style" C declarations, hence parse them as a DeclList
** until the opening "{" is parsed. Note that there is conflict with "const"
** and "volatile" above. This cannot be helped, so the decision is to move
** "const" and "volatile" to the function header, as they were not keywords in
** pre-ANSI C.
**
**
** (30) ® kSLex_Context kSLex_Decl "(" ")" • ":" -> ® kSLex_Context kSLex_Decl "(" ")" ":" kSLex_Context kSPrs_Expr •
** (31) ® kSLex_Context kSLex_Decl "(" ")" ":" kSLex_Context kSPrs_Expr • "," -> ® kSLex_Context kSLex_Decl "(" ")" ":" kSLex_Context kSPrs_Expr •
** (32) ® kSLex_Context kSLex_Decl "(" ")" ":" kSLex_Context kSPrs_Expr • "{" -> ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context "{" kSPrs_StmtList •
** Constructors are function headers followed by initialization expressions and
** a body.
**
**
** (37) ® kSLex_Context kSLex_Decl "(" ")" • "(" -> ® kSLex_Context kSLex_Decl • "("
** What we thought was a function header wasn't. It could have been the
** declaration of a pointer to a function, such as "void (*foo)(...)". Shift
** to function declaration mode again.
**
**
** (38) ® kSLex_Context kSLex_Decl "(" ")" • ??? -> ® kSLex_Context kSLex_Decl • ???
** Treat this as the end of a declaration. Reduce and pass the information
** upstream.
**
**
** (33) ® kSLex_Context kSLex_Decl • kSLex_Op -> ® kSLex_Context kSLex_Decl kSLex_Op •
** (34) ? kSLex_Op • kSLex_Op -> ? kSLex_Op kSLex_Op •
** (35) ? kSLex_Op • kSLex_ParsedId -> ? •
** (36) ? kSLex_Op • ??? -> ? • ???
** Operators are "*" and "&". The "*" are counted until a terminating token
** is scanned, at which point they are all removed from the stack. The
** operators are not displayed until they are removed.
**
**
** (39) ® kSLex_Context kSLex_Decl • kSLex_OpAssign -> ® kSLex_Context kSLex_Decl kSLex_OpAssign •
** (40) ® kSLex_Context kSLex_Decl kSLex_OpAssign • "{" -> ® kSLex_Context kSLex_Decl kSLex_OpAssign kSLex_Context "{" kSPrs_Expr •
** (41) ® kSLex_Context kSLex_Decl kSLex_OpAssign • ??? -> ® kSLex_Context kSLex_Decl kSLex_OpAssign kSLex_Context kSPrs_Expr • ???
** (42) ® kSLex_Context kSLex_Decl kSLex_OpAssign kSLex_Context kSPrs_Expr • ??? -> ® kSLex_Context kSLex_Decl • ???
** (44) ® kSLex_Context kSLex_Decl kSLex_OpAssign kSLex_Context "{" kSPrs_Expr • "}"-> ® kSLex_Context kSLex_Decl •
** (45) ? kSLex_Context "{" kSPrs_Expr • "{" -> ? kSLex_Context "{" kSPrs_Expr kSLex_Context "{" KSPrs_Expr •
** (46) ? kSLex_Context "{" kSPrs_Expr • "}" -> ? •
** (47) ? kSLex_Context "{" kSPrs_Expr • "," -> ? kSLex_Context "{" kSPrs_Expr •
** (48) ? kSLex_Context "{" kSPrs_Expr • kSPrs_Expr -> ? kSLex_Context "{" kSPrs_Expr •
** The other type of operator is the assignment operator, used for initializing
** declared variables. Note that if this is the initialization of a non-scalar
** that nested initializations are possible. The ? "{" ... "}" handle the
** nesting.
**
**
** (49) ® kSLex_Context kSLex_Decl kSLex_ParsedId • "(" -> ® kSLex_Context kSLex_Decl • "("
** (70) ® kSLex_Context kSLex_Decl kSLex_ParsedId • "[" -> ® kSLex_Context kSLex_Decl • "["
** (50) ® kSLex_Context kSLex_Decl kSLex_ParsedId • "," -> ® kSLex_Context kSLex_Decl • ","
** (51) ® kSLex_Context kSLex_Decl kSLex_ParsedId • ";" -> ® kSLex_Context kSLex_Decl • ";"
** (53) ® kSLex_Context kSLex_Decl kSLex_ParsedId • "}" -> ® kSLex_Context kSLex_Decl • "}"
** (68) ® kSLex_Context kSLex_Decl kSLex_ParsedId • ")" -> ® kSLex_Context kSLex_Decl • ")"
** (54) ® kSLex_Context kSLex_Decl kSLex_ParsedId • kSLex_ParsedId -> ® kSLex_Context kSLex_Decl kSLex_ParsedId •
** (55) ® kSLex_Context kSLex_Decl kSLex_ParsedId • kSLex_Op -> ® kSLex_Context kSLex_Decl • kSLex_Op
** (56) ® kSLex_Context kSLex_Decl kSLex_ParsedId • kSLex_Decl -> ® kSLex_Context kSLex_Decl •
** When an identifier is on the stack in a "® kSLex_Context kSLex_Decl kSLex_ParsedId •",
** it has not been written pending a resolution of what it is. These rules do some
** decisions about what it is.
**
**
** (43) ® kSLex_Context kSLex_Decl kSLex_ParsedId • ":" -> ® kSLex_Context kSLex_Decl kSLex_Context kSPrs_Expr •
** This is presumed to be a bitfield declaration. Treat it as such.
**
** (71) ® kSLex_Context kSLex_Decl kSLex_ParsedId • ??? -> ® kSLex_Context kSLex_Decl kSPrs_Expr • ???
** Any other token type will shift us out of this phase and into a new one. The
** one exception is for source newlines, which will be passed along as required.
**
**
** (57) ® kSLex_Context kSLex_Decl • "[" -> ® kSLex_Context kSLex_Decl kSLex_Context "[" kSPrs_Expr •
** (58) ® kSLex_Context kSLex_Decl kSLex_Context "[" kSPrs_Expr • "," -> ® kSLex_Context kSLex_Decl kSLex_Context "[" kSPrs_Expr •
** (59) ® kSLex_Context kSLex_Decl kSLex_Context "[" kSPrs_Expr • "]" -> ® kSLex_Context kSLex_Decl •
** Reduce bracketed expressions
**
**
** (72) ® kSLex_Context kSLex_Decl • kSLex_Value -> ® kSLex_Context kSLex_Decl kSLex_Context kSPrs_Expr • kSLex_Value
** (73) ® kSLex_Context kSLex_Decl kSLex_Context kSPrs_Expr • ??? -> ® kSLex_Context kSLex_Decl • ???
** The declaration might have an expression within it. Consequently, do the
** expression. When the expression is finished, reduce to a kSLex_Decl and see
** what happens
**
**
** (60) ? "(" • "(" -> ? "(" "(" •
** (61) ? "(" • ")" -> ? •
** (62) ? "(" • "[" -> ? "(" "[" •
** (63) ? "(" • ??? -> ? "(" kSLex_Context kSPrs_Expr • ???
** (64) ? "(" kSLex_Context kSPrs_Expr • ")" -> ? kSLex_ParsedId •
** (65) ? "(" kSLex_Context kSPrs_Expr • "," -> ? "(" kSLex_Context kSPrs_Expr •
** (66) ? "(" kSLex_Context kSPrs_Decl • ")" -> ? kSLex_ParsedId •
** (67) ? "(" kSLex_Context kSPrs_Decl • "," -> ? "(" kSLex_Context kSPrs_Decl •
** Balanced brackets are nested or removed from the stack. Commas within
** balanced brackets separate expressions and declarations. These are done
** last as they are least specific.
*/
#pragma segment ParserActions
Boolean
PrsDecl::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
26, kSLex_RCurly, 8, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen, kSLex_Context, kSLex_LCurly, kSPrs_StmtList,
31, kSLex_Comma, 8, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen, kSLex_Colon, kSLex_Context, kSPrs_Expr,
32, kSLex_LCurly, 8, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen, kSLex_Colon, kSLex_Context, kSPrs_Expr,
29, kSLex_LCurly, 7, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen, kSLex_Context, kSPrs_DeclList,
44, kSLex_RCurly, 7, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_OpAssign, kSLex_Context, kSLex_LCurly, kSPrs_Expr,
18, kSLex_RParen, 6, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_Context, kSPrs_Decl,
19, kSLex_Comma, 6, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_Context, kSPrs_Decl,
58, kSLex_Comma, 6, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_Context, kSLex_LBrace, kSPrs_Expr,
59, kSLex_RBrace, 6, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_Context, kSLex_LBrace, kSPrs_Expr,
// 20, kSLex_DeclConst, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
// 21, kSLex_DeclVolatile, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
22, kSLex_Op, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
23, kSLex_SemiColon, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
24, kSLex_Comma, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
25, kSLex_LCurly, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
27, kSLex_Decl, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
27, kSLex_Struct, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
28, kSLex_ParsedId, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
30, kSLex_Colon, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
37, kSLex_LParen, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
40, kSLex_LCurly, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_OpAssign,
43, kSLex_Colon, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_ParsedId,
49, kSLex_LParen, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_ParsedId,
50, kSLex_Comma, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_ParsedId,
51, kSLex_SemiColon, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_ParsedId,
53, kSLex_RCurly, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_ParsedId,
54, kSLex_ParsedId, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_ParsedId,
55, kSLex_Op, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_ParsedId,
56, kSLex_Decl, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_ParsedId,
68, kSLex_RParen, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_ParsedId,
70, kSLex_LBrace, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_ParsedId,
7, kSLex_SemiColon, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
8, kSLex_Comma, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
9, kSLex_RParen, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
10, kSPrs_DeclType, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
11, kSLex_Decl, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
12, kSPrs_Decl, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
13, kSLex_ParsedId, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
15, kSLex_Struct, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
16, kSLex_LCurly, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
17, kSLex_LParen, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
33, kSLex_Op, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
// 39, kSLex_OpAssign, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
45, kSLex_LCurly, 3, kSLex_Context, kSLex_LCurly, kSPrs_Expr,
46, kSLex_RCurly, 3, kSLex_Context, kSLex_LCurly, kSPrs_Expr,
47, kSLex_Comma, 3, kSLex_Context, kSLex_LCurly, kSPrs_Expr,
48, kSPrs_Expr, 3, kSLex_Context, kSLex_LCurly, kSPrs_Expr,
57, kSLex_LBrace, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
64, kSLex_RParen, 3, kSLex_LParen, kSLex_Context, kSPrs_Expr,
65, kSLex_Comma, 3, kSLex_LParen, kSLex_Context, kSPrs_Expr,
66, kSLex_RParen, 3, kSLex_LParen, kSLex_Context, kSPrs_Decl,
67, kSLex_Comma, 3, kSLex_LParen, kSLex_Context, kSPrs_Decl,
69, kSLex_RCurly, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
72, kSLex_Value, 3, kSPrs_Decl, kSLex_Context, kSLex_Decl,
6, kSLex_Decl, 2, kSPrs_Decl, kSLex_OpBNot,
0, kSLex_SemiColon, 1, kSPrs_Decl,
1, kSPrs_Decl, 1, kSPrs_Decl,
2, kSLex_Struct, 1, kSPrs_Decl,
3, kSLex_ParsedId, 1, kSPrs_Decl,
4, kSLex_Decl, 1, kSPrs_Decl,
5, kSLex_Op, 1, kSPrs_Decl,
76, kSLex_Ellipsis, 1, kSPrs_Decl,
74, kSLex_Value, 1, kSPrs_Decl,
34, kSLex_Op, 1, kSLex_Op,
35, kSLex_ParsedId, 1, kSLex_Op,
60, kSLex_LParen, 1, kSLex_LParen,
61, kSLex_RParen, 1, kSLex_LParen,
62, kSLex_LBrace, 1, kSLex_LParen,
42, -1, 6, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_OpAssign, kSLex_Context, kSPrs_Expr,
38, -1, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_LParen, kSLex_RParen,
73, -1, 5, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_Context, kSPrs_Expr,
41, -1, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_OpAssign,
71, -1, 4, kSPrs_Decl, kSLex_Context, kSLex_Decl, kSLex_ParsedId,
75, -1, 3, kSPrs_Decl, kSLex_Context, kSPrs_Expr,
14, -1, 2, kSPrs_Decl, kSLex_OpBNot,
36, -1, 1, kSLex_Op,
63, -1, 1, kSLex_LParen,
-1, -1, 0
//ƒ+
};
/*
** Hack. Various states are hidden under other states.
**
** ( 5) -> (52)
** The operator might a "~", part of a destructor name.
**
** (27) -> (20)
** (27) -> (21)
** Both "const" and "volatile" are MinorType()s of kSLex_Decl.
**
** (33) -> (39)
** The kSLex_Op might be a kSLex_OpAssign.
**
** Check the type of aToken and modify the state index.
*/
short anIndex = aParser->FindHandle(aToken->Type(), handles);
switch (anIndex)
{
case 5:
if (aToken->MinorType() == kSLex_OpBNot)
anIndex = 52;
break;
case 27:
switch (aToken->MinorType())
{
case kSLex_DeclConst: anIndex = 20; break;
case kSLex_DeclVolatile: anIndex = 21; break;
}
break;
case 33:
if (aToken->MinorType() == kSLex_OpAssign)
anIndex = 39;
break;
}
DEBUGPARSER(Decl, anIndex);
switch (anIndex)
{
case 0: // ® • ";" -> • kSPrs_Decl
aFormat->SetGlue(gFS_decl0);
aFormat->Semi();
aFormat->Display(aToken);
aParser->Reduce(this, 1);
break;
case 1: // ® • kSPrs_Decl -> • kSPrs_Decl
aParser->Reduce(aToken, 1);
break;
case 2: // ® • "struct" -> ® kSLex_Context kSLex_Decl kSPrs_Struct • "struct"
aFormat->OpenContext();
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aParser->Shift(&gContext);
aParser->Shift(&gLexDecl);
aParser->Shift(&gPrsStruct);
aParser->Parse(aToken);
break;
case 3: // ® • kSLex_ParsedId -> ® kSLex_Context kSLex_Decl •
case 4: // ® • kSLex_Decl -> ® kSLex_Context kSLex_Decl •
case 76: // ® • kSLex_Ellipsis -> ® kSLex_Context kSLex_Decl •
aFormat->OpenContext();
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aFormat->SetGlue(gFS_decl0);
aFormat->Name();
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(&gLexDecl);
break;
case 5: // ® • kSLex_Op -> ® kSLex_Context kSLex_Decl •
aFormat->OpenContext();
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aFormat->SetGlue(gFS_decl0);
aParser->Shift(&gContext);
aParser->Shift(&gLexDecl);
return (Accept(aToken, aParser));
case 52: // ® • kSLex_OpBNot -> ® kSLex_OpBNot •
aParser->Shift(&gLexBNot);
break;
case 6: // ® kSLex_OpBNot • kSLex_ParsedId -> ® kSLex_Context kSLex_Decl kSLex_ParsedId •
aFormat->OpenContext();
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aFormat->SetGlue(gFS_decl0);
aParser->TopItem(&gContext);
aParser->Shift(&gLexDecl);
aParser->Shift(new PrsDestructor(aToken));
break;
case 14: // ® kSLex_OpBNot • ??? -> ® kSLex_Context kSLex_Decl • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->OpenContext();
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aFormat->SetGlue(gFS_decl0);
aFormat->Display(aParser->TopItem());
aParser->TopItem(&gContext);
aParser->Shift(&gLexDecl);
return (Accept(aToken, aParser));
case 74: // ® • kSLex_Value -> ® kSLex_Context kSPrs_Expr • kSLex_Value
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aFormat->SetGlue(gFS_decl0);
aParser->Shift(&gContext);
aParser->Shift(&gPrsExpr);
aParser->Parse(aToken);
break;
case 75: // ® kSLex_Context kSPrs_Expr • ??? -> ® kSLex_Context kSLex_Decl • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->RestoreIndent();
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aParser->TopItem(&gLexDecl);
return (Accept(aToken, aParser));
case 7: // ® kSLex_Context kSLex_Decl • ";" -> ® • kSPrs_Decl
aFormat->SetGlue(gFS_decl10);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(2);
return (Accept(&gPrsDecl, aParser));
case 8: // ® kSLex_Context kSLex_Decl • "," -> ® • ","
case 9: // ® kSLex_Context kSLex_Decl • ")" -> ® • ")"
case 69: // ® kSLex_Context kSLex_Decl • "}" -> ® • "}"
aFormat->CloseContext();
aParser->Drop(2);
return (Accept(aToken, aParser));
case 10: // ® kSLex_Context kSLex_Decl • kSPrs_DeclType -> ® kSLex_Context kSLex_Decl •
break;
case 11: // ® kSLex_Context kSLex_Decl • kSLex_Decl -> ® kSLex_Context kSLex_Decl •
aFormat->Name();
aFormat->Display(aToken);
break;
case 12: // ® kSLex_Context kSLex_Decl • kSPrs_Decl -> ® • kSPrs_Decl
aFormat->CloseContext();
aParser->Drop(2);
return (Accept(aToken, aParser));
case 15: // ® kSLex_Context kSLex_Decl • "struct" -> ® • "struct"
aFormat->Name();
aFormat->CloseContext();
aParser->Drop(2);
return (Accept(aToken, aParser));
case 13: // ® kSLex_Context kSLex_Decl • kSLex_ParsedId -> ® kSLex_Context kSLex_Decl kSLex_ParsedId •
aParser->Shift(aToken);
break;
case 16: // ® kSLex_Context kSLex_Decl • "{" -> ® kSLex_Context kSLex_Decl "(" ")" • "{"
aFormat->RestoreIndent();
aParser->Shift(&gLexLParen);
aParser->Shift(&gLexRParen);
return (Accept(aToken, aParser));
case 17: // ® kSLex_Context kSLex_Decl • "(" -> ® kSLex_Context kSLex_Decl "(" kSLex_Context kSPrs_Decl •
aFormat->RestoreIndent();
aFormat->OpenContext();
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aFormat->SetGlue(gFS_fundef3);
aFormat->Display(aToken);
aParser->Shift(aToken);
aParser->Shift(&gContext);
aParser->Shift(&gPrsDecl);
break;
case 18: // ® kSLex_Context kSLex_Decl "(" kSLex_Context kSPrs_Decl • ")" -> ® kSLex_Context kSLex_Decl "(" ")" •
aFormat->SetGlue(gFS_fundef6);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(2);
aParser->Shift(aToken);
break;
case 19: // ® kSLex_Context kSLex_Decl "(" kSLex_Context kSPrs_Decl • "," -> ® kSLex_Context kSLex_Decl "(" kSPrs_Decl •
aFormat->SetGlue(gFS_fundef4);
aFormat->Display(aToken);
break;
case 20: // ® kSLex_Context kSLex_Decl "(" ")" • "const -> ® kSLex_Context kSLex_Decl "(" ")" •
case 21: // ® kSLex_Context kSLex_Decl "(" ")" • "volatile" -> ® kSLex_Context kSLex_Decl "(" ")" •
aFormat->SetGlue((FormatString)"!n s# •");
aFormat->Display(aToken);
break;
case 22: // ® kSLex_Context kSLex_Decl "(" ")" • kSLex_Op -> ® kSLex_Context kSLex_Decl • kSLex_Op
case 23: // ® kSLex_Context kSLex_Decl "(" ")" • ";" -> ® kSLex_Context kSLex_Decl • ";"
case 24: // ® kSLex_Context kSLex_Decl "(" ")" • "," -> ® kSLex_Context kSLex_Decl • ","
aParser->Drop(2);
return (Accept(aToken, aParser));
case 25: // ® kSLex_Context kSLex_Decl "(" ")" • "{" -> ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context "{" kSPrs_StmtList •
aFormat->OpenContext();
DEBUGSETCONTEXT(setFundefContext)
setFundefContext(aFormat);
aFormat->SetLCurly(gFS_fundef11);
aFormat->SetRCurly(gFS_fundef12);
aFormat->LCurly();
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsStmtList);
break;
case 26: // ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context "{" kSPrs_StmtList • "}" -> • kSPrs_Decl
aFormat->RCurly();
aFormat->Display(aToken);
aFormat->CloseContext();
aFormat->CloseContext();
aParser->Reduce(&gPrsDecl, 7);
break;
case 27: // ® kSLex_Context kSLex_Decl "(" ")" • kSLex_Decl -> ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context kSPrs_DeclList • kSLex_Decl
// case 27: // ® kSLex_Context kSLex_Decl "(" ")" • "struct" -> ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context kSPrs_DeclList • "struct"
case 28: // ® kSLex_Context kSLex_Decl "(" ")" • kSLex_ParsedId -> ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context kSPrs_DeclList • kSLex_ParsedId
aFormat->RestoreIndent();
aFormat->OpenContext();
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aFormat->SetGlue(gFS_fundef7);
aParser->Shift(&gContext);
aParser->Shift(&gPrsDeclList);
aParser->Parse(aToken);
break;
case 29: // ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context kSPrs_DeclList • "{" -> ® kSLex_Context kSLex_Decl "(" ")" • "{"
aFormat->CloseContext();
aParser->Drop(2);
return (Accept(aToken, aParser));
case 30: // ® kSLex_Context kSLex_Decl "(" ")" • ":" -> ® kSLex_Context kSLex_Decl "(" ")" ":" kSLex_Context kSPrs_Expr •
aFormat->SetGlue(gFS_fundef8);
aFormat->Display(aToken);
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aParser->Shift(aToken);
aParser->Shift(&gContext);
aParser->Shift(&gPrsExpr);
break;
case 31: // ® kSLex_Context kSLex_Decl "(" ")" ":" kSLex_Context kSPrs_Expr • "," -> ® kSLex_Context kSLex_Decl "(" ")" ":" kSLex_Context kSPrs_Expr •
aFormat->RestoreIndent();
aFormat->SetGlue(gFS_fundef10);
aFormat->Display(aToken);
break;
case 32: // ® kSLex_Context kSLex_Decl "(" ")" ":" kSLex_Context kSPrs_Expr • "{" -> ® kSLex_Context kSLex_Decl "(" ")" kSLex_Context "{" kSPrs_StmtList •
aFormat->RestoreIndent();
DEBUGSETCONTEXT(setFundefContext)
setFundefContext(aFormat);
aFormat->SetLCurly(gFS_fundef13);
aFormat->SetRCurly(gFS_fundef14);
aFormat->LCurly();
aFormat->Display(aToken);
aParser->Drop(3);
aParser->Shift(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsStmtList);
break;
case 37: // ® kSLex_Context kSLex_Decl "(" ")" • "(" -> ® kSLex_Context kSLex_Decl • "("
case 38: // ® kSLex_Context kSLex_Decl "(" ")" • ??? -> ® kSLex_Context kSLex_Decl • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aParser->Drop(2);
return (Accept(aToken, aParser));
case 33: // ® kSLex_Context kSLex_Decl • kSLex_Op -> ® kSLex_Context kSLex_Decl kSLex_Op •
case 34: // ? kSLex_Op • kSLex_Op -> ? kSLex_Op kSLex_Op •
aParser->Shift(aToken);
break;
case 35: // ? kSLex_Op • kSLex_ParsedId -> ? •
case 36: // ? kSLex_Op • ??? -> ? • ???
{
short nOperators = 0;
while (aParser->Pick(nOperators)->Type() == kSLex_Op)
nOperators++;
// if the token is a right paren, this declaration is most likely a
// cast. We don't make casts as wide as possible. However, we might
// want a space between the type and the operators, so we check
// DeclLeft()
if (aToken->Type() != kSLex_RParen)
aFormat->DeclPadStart(nOperators);
else if (!aFormat->DeclLeft())
aFormat->ExecuteGlue((FormatString)"s#");
short i = nOperators;
while (i--)
aFormat->Display(aParser->Pick(i));
// If this is not a cast, then pad it out if required.
if (aToken->Type() != kSLex_RParen)
aFormat->DeclPadEnd();
aParser->Drop(nOperators);
}
if (anIndex == 35)
aFormat->Display(aToken);
else
return (Accept(aToken, aParser));
break;
case 39: // ® kSLex_Context kSLex_Decl • kSLex_OpAssign -> ® kSLex_Context kSLex_Decl kSLex_OpAssign •
aFormat->SetGlue(gFS_decl2);
aFormat->Display(aToken);
aParser->Shift(&gLexOpAssign);
break;
case 40: // ® kSLex_Context kSLex_Decl kSLex_OpAssign • "{" -> ® kSLex_Context kSLex_Decl kSLex_OpAssign kSLex_Context "{" kSPrs_Expr •
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aFormat->SetGlue(gFS_decl5);
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsExpr);
break;
case 41: // ® kSLex_Context kSLex_Decl kSLex_OpAssign • ??? -> ® kSLex_Context kSLex_Decl kSLex_OpAssign kSLex_Context kSPrs_Expr • ???
if (aToken->Type() == kSLex_NewLine && !aFormat->PassSourceNewLines())
{
aParser->Shift(&gPrsNewLine);
return (true);
}
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aParser->Shift(&gContext);
aParser->Shift(&gPrsExpr);
aParser->Parse(aToken);
break;
case 42: // ® kSLex_Context kSLex_Decl kSLex_OpAssign kSLex_Context kSPrs_Expr • ??? -> ® kSLex_Context kSLex_Decl • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->CloseContext();
aParser->Drop(3);
return (Accept(aToken, aParser));
case 44: // ® kSLex_Context kSLex_Decl kSLex_OpAssign kSLex_Context "{" kSPrs_Expr • "}"-> ® kSLex_Context kSLex_Decl •
aFormat->SetGlue(gFS_decl9);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(4);
break;
case 45: // ? kSLex_Context "{" kSPrs_Expr • "{" -> ? kSLex_Context "{" kSPrs_Expr kSLex_Context "{" KSPrs_Expr •
aFormat->OpenContext();
aFormat->SetGlue(gFS_decl6);
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsExpr);
break;
case 46: // ? kSLex_Context "{" kSPrs_Expr • "}" -> ? •
aFormat->SetGlue(gFS_decl7);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(3);
break;
case 47: // ? kSLex_Context "{" kSPrs_Expr • "," -> ? kSLex_Context "{" kSPrs_Expr •
aFormat->SetGlue(gFS_decl8);
aFormat->Display(aToken);
break;
case 48: // ? kSLex_Context "{" kSPrs_Expr • kSPrs_Expr -> ? kSLex_Context "{" kSPrs_Expr •
break;
case 49: // ® kSLex_Context kSLex_Decl kSLex_ParsedId • "(" -> ® kSLex_Context kSLex_Decl • "("
case 70: // ® kSLex_Context kSLex_Decl kSLex_ParsedId • "[" -> ® kSLex_Context kSLex_Decl • "["
case 50: // ® kSLex_Context kSLex_Decl kSLex_ParsedId • "," -> ® kSLex_Context kSLex_Decl • ","
case 51: // ® kSLex_Context kSLex_Decl kSLex_ParsedId • ";" -> ® kSLex_Context kSLex_Decl • ";"
case 53: // ® kSLex_Context kSLex_Decl kSLex_ParsedId • "}" -> ® kSLex_Context kSLex_Decl • "}"
case 68: // ® kSLex_Context kSLex_Decl kSLex_ParsedId • ")" -> ® kSLex_Context kSLex_Decl • ")"
aFormat->Name();
aFormat->Display(aParser->TopItem());
aParser->Drop(1);
return (Accept(aToken, aParser));
case 54: // ® kSLex_Context kSLex_Decl kSLex_ParsedId • kSLex_ParsedId -> ® kSLex_Context kSLex_Decl kSLex_ParsedId •
aFormat->Name();
aFormat->Display(aParser->TopItem());
aParser->TopItem(aToken);
break;
case 55: // ® kSLex_Context kSLex_Decl kSLex_ParsedId • kSLex_Op -> ® kSLex_Context kSLex_Decl • kSLex_Op
aFormat->Name();
aFormat->Display(aParser->TopItem());
aParser->Drop(1);
return (Accept(aToken, aParser));
case 56: // ® kSLex_Context kSLex_Decl kSLex_ParsedId • kSLex_Decl -> ® kSLex_Context kSLex_Decl •
aFormat->Name();
aFormat->Display(aParser->TopItem());
aFormat->Name();
aFormat->Display(aToken);
aParser->Drop(1);
break;
case 43: // ® kSLex_Context kSLex_Decl kSLex_ParsedId • ":" -> ® kSLex_Context kSLex_Decl kSLex_Context kSPrs_Expr •
aFormat->Name();
aFormat->Display(aParser->TopItem());
aFormat->Display(aToken);
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aParser->TopItem(&gContext);
aParser->Shift(&gPrsExpr);
break;
case 71: // ® kSLex_Context kSLex_Decl kSLex_ParsedId • ??? -> ® kSLex_Context kSLex_Decl kSPrs_Expr • ???
if (aToken->Type() == kSLex_NewLine && !aFormat->PassSourceNewLines())
{
aParser->Shift(&gPrsNewLine);
return (true);
}
aFormat->Name();
aFormat->Display(aParser->TopItem());
aParser->Drop(1);
return (Accept(aToken, aParser));
case 57: // ® kSLex_Context kSLex_Decl • "[" -> ® kSLex_Context kSLex_Decl kSLex_Context "[" kSPrs_Expr •
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aFormat->LParen();
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsExpr);
break;
case 58: // ® kSLex_Context kSLex_Decl kSLex_Context "[" kSPrs_Expr • "," -> ® kSLex_Context kSLex_Decl kSLex_Context "[" kSPrs_Expr •
aFormat->Comma();
aFormat->Display(aToken);
break;
case 59: // ® kSLex_Context kSLex_Decl kSLex_Context "[" kSPrs_Expr • "]" -> ® kSLex_Context kSLex_Decl •
aFormat->RParen();
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(3);
break;
case 72: // ® kSLex_Context kSLex_Decl • kSLex_Value -> ® kSLex_Context kSLex_Decl kSLex_Context kSPrs_Expr • kSLex_Value
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aParser->Shift(&gContext);
aParser->Shift(&gPrsExpr);
aParser->Parse(aToken);
break;
case 73: // ® kSLex_Context kSLex_Decl kSLex_Context kSPrs_Expr • ??? -> ® kSLex_Context kSLex_Decl • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->CloseContext();
aParser->Drop(2);
return (Accept(aToken, aParser));
case 61: // ? "(" • ")" -> ? •
aFormat->RParen();
aFormat->Display(aToken);
aParser->Drop(1);
break;
case 60: // ? "(" • "(" -> ? "(" "(" •
case 62: // ? "(" • "[" -> ? "(" "[" •
aFormat->LParen();
aFormat->Display(aToken);
aParser->Shift(aToken);
break;
case 63: // ? "(" • ??? -> ? "(" kSLex_Context kSPrs_Expr • ???
if (aToken->Type() == kSLex_NewLine && !aFormat->PassSourceNewLines())
{
aParser->Shift(&gPrsNewLine);
return (true);
}
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aParser->Shift(&gContext);
aParser->Shift(&gPrsExpr);
aParser->Parse(aToken);
break;
case 64: // ? "(" kSLex_Context kSPrs_Expr • ")" -> ? kSLex_ParsedId •
case 66: // ? "(" kSLex_Context kSPrs_Decl • ")" -> ? kSLex_ParsedId •
aFormat->RParen();
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(3);
aParser->Shift(&gLexParsedId);
break;
case 65: // ? "(" kSLex_Context kSPrs_Expr • "," -> ? "(" kSLex_Context kSPrs_Expr •
aFormat->Comma();
aFormat->Display(aToken);
break;
case 67: // ? "(" kSLex_Context kSPrs_Decl • "," -> ? "(" kSLex_Context kSPrs_Decl •
aFormat->Comma();
aFormat->Display(aToken);
break;
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_Do ( 9)
** ( 0) ® • "do" -> ® kSLex_Context •
**
** ( 1) ® kSLex_Context • ";" -> ® kSLex_Context ";" •
** ( 2) ® kSLex_Context • "{" -> ® kSLex_Context "{" kSPrs_StmtList •
** ( 3) ® kSLex_Context • ??? -> ® kSLex_Context ";" kSPrs_Stmt • ???
**
** ( 4) ® kSLex_Context "{" kSPrs_StmtList • "}" -> ® kSLex_Context ";"
**
** ( 5) ® kSLex_Context ";" • kSPrs_Stmt -> ® kSLex_Context ";" •
** ( 6) ® kSLex_Context ";" • "while" -> ® kSLex_Context "while" •
**
** ( 7) ® kSLex_Context "while" • "(" -> ® kSLex_Context "(" kSPrs_Expr •
**
** ( 8) ® kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_Context ")" •
**
** ( 9) ® kSLex_Context ")" • ";" -> • kSPrs_Stmt
**
** Emit the "do" (0) and the statement following it (1) and (2). After the
** statement has been parsed (3), wait for the "while" (4), the "(" (5), the
** conditional expression and closing ")" (6) and the close ";" (7)
*/
#pragma segment ParserActions
Boolean
PrsDo::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
8, kSLex_RParen, 4, kSPrs_Do, kSLex_Context, kSLex_LParen, kSPrs_Expr,
4, kSLex_RCurly, 4, kSPrs_Do, kSLex_Context, kSLex_LCurly, kSPrs_StmtList,
5, kSPrs_Stmt, 3, kSPrs_Do, kSLex_Context, kSLex_SemiColon,
6, kSLex_While, 3, kSPrs_Do, kSLex_Context, kSLex_SemiColon,
7, kSLex_LParen, 3, kSPrs_Do, kSLex_Context, kSLex_While,
9, kSLex_SemiColon, 3, kSPrs_Do, kSLex_Context, kSLex_RParen,
1, kSLex_SemiColon, 2, kSPrs_Do, kSLex_Context,
2, kSLex_LCurly, 2, kSPrs_Do, kSLex_Context,
0, kSLex_Do, 1, kSPrs_Do,
3, -1, 2, kSPrs_Do, kSLex_Context,
-1, -1, 0
//ƒ+
};
short anIndex = aParser->FindHandle(aToken->Type(), handles);
DEBUGPARSER(Do, anIndex);
switch (anIndex)
{
case 0: // ® • "do" -> ® kSLex_Context •
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aFormat->SetGlue(gFS_do0);
aFormat->Display(aToken);
aParser->Shift(&gContext);
break;
case 1: // ® kSLex_Context • ";" -> ® kSLex_Context ";" •
aFormat->SetGlue(gFS_do1);
aFormat->Display(aToken);
aParser->TopItem(&gLexSemiColon);
break;
case 2: // ® kSLex_Context • "{" -> ® kSLex_Context "{" kSPrs_StmtList •
aFormat->SetGlue(gFS_do2);
aFormat->Display(aToken);
aParser->Shift(aToken);
aParser->Shift(&gPrsStmtList);
break;
case 3: // ® kSLex_Context • ??? -> ® kSLex_Context ";" kSPrs_Stmt • ???
if (aToken->Type() == kSLex_NewLine && !aFormat->PassSourceNewLines())
{
aParser->Shift(&gPrsNewLine);
return (true);
}
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->SetGlue(gFS_do3);
aParser->Shift(&gLexSemiColon);
aParser->Shift(&gPrsStmt);
aParser->Parse(aToken);
break;
case 4: // ® kSLex_Context "{" kSPrs_StmtList • "}" -> ® kSLex_Context ";"
aFormat->SetGlue(gFS_do4);
aFormat->Display(aToken);
aParser->Drop(2);
aParser->Shift(&gLexSemiColon);
break;
case 5: // ® kSLex_Context ";" • kSPrs_Stmt -> ® kSLex_Context ";" •
break;
case 6: // ® kSLex_Context ";" • "while" -> ® kSLex_Context "while" •
aFormat->RestoreIndent();
aFormat->SetGlue(gFS_do5);
aFormat->Display(aToken);
aParser->TopItem(aToken);
break;
case 7: // ® kSLex_Context "while" • "(" -> ® kSLex_Context "(" kSPrs_Expr •
aFormat->SetGlue(gFS_do6);
aFormat->Display(aToken);
aParser->TopItem(aToken);
aParser->Shift(&gPrsExpr);
break;
case 8: // ® kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_Context ")" •
aFormat->RParen();
aFormat->Display(aToken);
aParser->Drop(2);
aParser->Shift(aToken);
break;
case 9: // ® kSLex_Context ")" • ";" -> • kSPrs_Stmt
aFormat->Semi();
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Reduce(&gPrsStmt, 3);
break;
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_If (15)
** ( 0) ® • "if" -> ® kSLex_Context •
** ( 1) ® kSLex_Context • "(" -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr
** ( 2) ® kSLex_Context kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr
** ( 3) ® kSLex_Context kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_Context ")" •
** (13) ® kSLex_Context kSLex_Context "(" kSPrs_Expr • "{" -> ® kSLex_Context ")" • "{"
** Parse the "if ( expr )". There should be a statement following.
** The '® kSPrs_Expr • "{"' case is present because of a test case
** where the closing paren was inside both parts of a #ifdef. Thank
** you very much.
**
** ( 5) ® kSLex_Context ")" • ";" -> ® kSLex_Context ";" •
** The statement following is empty. Let it live. Yield '® kSLex_Context ";"'
** on the stack, indicating the then-part has been parse. This indicates
** that the then-part was not a compound statement.
**
** ( 7) ® kSLex_Context ")" • ??? -> ® kSLex_Context ")" kSLex_Context kSPrs_Stmt • ???
** ( 6) ® kSLex_Context ")" kSLex_Context • kSPrs_Stmt -> ® kSLex_Context ";" •
** Assume that this is some other sort of statement. Upon completion,
** indicate that the then-part has been parsed and that the then-part
** was not a compound statement.
**
** ( 4) ® kSLex_Context ")" • "{" -> ® kSLex_Context kSLex_Context "{" kSPrs_StmtList •
** ( 8) ® kSLex_Context kSLex_Context "{" kSPrs_StmtList • "}" -> ® kSLex_Context kSLex_Context "}" •
** The statement following is a compound statement. Yield '® kSLex_Context kSLex_Context "}"'
** when the closing curly appears. This indicates that the then-part was
** a compound statement. An "else" following might be handled differently
** than in cases (5) and (6). Note that the "}" is not displayed, but
** deferred until we know if an "else" or something else follows.
**
** ( 9) ® kSLex_Context ";" • "else" -> ® kSLex_Context ";" kSPrs_Else • "else"
** (10) ® kSLex_Context ";" • kSPrs_Else -> • kSPrs_Stmt
** (14) ® kSLex_Context kSLex_Context "}" • "else" -> ® kSLex_Context ";" kSPrs_Else • "else"
** (12) ® kSLex_Context ")" kSLex_Context kSPrs_Stmt • "else" -> ® kSLex_Context ")" • kSPrs_Stmt "else"
** The "else" part follows. Use the kSPrs_Else object to parse "else"
** and "else if" combinations. When done, they yield a kSPrs_Else.
** Again, because of macros, the kSPrs_Stmt might not appear. When the
** "else" keyword appears, assume the statement came through and handle
** the "else". Note that the ";" and "}" cases are distinguised because
** of potentially different formatting in these cases.
**
** (11) ® kSLex_Context ";" • ??? -> • kSPrs_Stmt ???
** (15) ® kSLex_Context kSLex_Context "}" • ??? -> ® kSLex_Context ";" • ???
** If the then-part is followed by something other than a "else", reduce
** the if to a statement and proceed. If the then-part was a compound
** statement, then convert to a normal statement and let the normal statement
** mode handle the token.
*/
#pragma segment ParserActions
Boolean
PrsIf::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
8, kSLex_RCurly, 5, kSPrs_If, kSLex_Context, kSLex_Context, kSLex_LCurly, kSPrs_StmtList,
2, kSLex_Comma, 5, kSPrs_If, kSLex_Context, kSLex_Context, kSLex_LParen, kSPrs_Expr,
3, kSLex_RParen, 5, kSPrs_If, kSLex_Context, kSLex_Context, kSLex_LParen, kSPrs_Expr,
12, kSLex_Else, 5, kSPrs_If, kSLex_Context, kSLex_RParen, kSLex_Context, kSPrs_Stmt,
13, kSLex_LCurly, 5, kSPrs_If, kSLex_Context, kSLex_Context, kSLex_RParen, kSPrs_Expr,
6, kSPrs_Stmt, 4, kSPrs_If, kSLex_Context, kSLex_RParen, kSLex_Context,
14, kSLex_Else, 4, kSPrs_If, kSLex_Context, kSLex_Context, kSLex_RCurly,
4, kSLex_LCurly, 3, kSPrs_If, kSLex_Context, kSLex_RParen,
5, kSLex_SemiColon, 3, kSPrs_If, kSLex_Context, kSLex_RParen,
9, kSLex_Else, 3, kSPrs_If, kSLex_Context, kSLex_SemiColon,
10, kSPrs_Else, 3, kSPrs_If, kSLex_Context, kSLex_SemiColon,
1, kSLex_LParen, 2, kSPrs_If, kSLex_Context,
0, kSLex_If, 1, kSPrs_If,
15, -1, 4, kSPrs_If, kSLex_Context, kSLex_Context, kSLex_RCurly,
7, -1, 3, kSPrs_If, kSLex_Context, kSLex_RParen,
11, -1, 3, kSPrs_If, kSLex_Context, kSLex_SemiColon,
-1, -1, 0
//ƒ+
};
short anIndex = aParser->FindHandle(aToken->Type(), handles);
DEBUGPARSER(If, anIndex);
switch (anIndex)
{
case 0: // ® • "if" -> ® kSLex_Context •
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aFormat->SetGlue(gFS_if0);
aFormat->Display(aToken);
aParser->Shift(&gContext);
break;
case 1: // ® kSLex_Context • "(" -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
aFormat->OpenContext();
aFormat->SetGlue(gFS_if1);
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsExpr);
break;
case 2: // ® kSLex_Context kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr
aFormat->Comma();
aFormat->Display(aToken);
break;
case 3: // ® kSLex_Context kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_Context ")" •
aFormat->SetGlue(gFS_if2);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(3);
aParser->Shift(&gLexRParen);
break;
case 4: // ® kSLex_Context ")" • "{" -> ® kSLex_Context kSLex_Context "{" kSPrs_StmtList •
aFormat->OpenContext();
aFormat->SetGlue(gFS_if4);
aFormat->Display(aToken);
aParser->TopItem(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsStmtList);
break;
case 5: // ® kSLex_Context ")" • ";" -> ® kSLex_Context ";" •
aFormat->SetGlue(gFS_if3);
aFormat->Display(aToken);
aFormat->RestoreIndent();
aParser->TopItem(&gLexSemiColon);
break;
case 6: // ® kSLex_Context ")" kSLex_Context • kSPrs_Stmt -> ® kSLex_Context ";" •
aFormat->CloseContext();
aParser->Drop(2);
aParser->Shift(&gLexSemiColon);
break;
case 7: // ® kSLex_Context ")" • ??? -> ® kSLex_Context ")" kSLex_Context kSPrs_Stmt • ???
if (aToken->Type() == kSLex_NewLine && !aFormat->PassSourceNewLines())
{
aParser->Shift(&gPrsNewLine);
return (true);
}
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->OpenContext();
aFormat->SetGlue(gFS_if7);
aParser->Shift(&gContext);
aParser->Shift(&gPrsStmt);
aParser->Parse(aToken);
break;
case 8: // ® kSLex_Context kSLex_Context "{" kSPrs_StmtList • "}" -> ® kSLex_Context kSLex_Context "}" •
aParser->Drop(2);
aParser->Shift(aToken);
break;
case 9: // ® kSLex_Context ";" • "else" -> ® kSLex_Context ";" kSPrs_Else • "else"
aParser->Shift(&gPrsElse);
aParser->Parse(aToken);
break;
case 10: // ® kSLex_Context ";" • kSPrs_Else -> • kSPrs_Stmt
aFormat->CloseContext();
aParser->Reduce(&gPrsStmt, 3);
break;
case 11: // ® kSLex_Context ";" • ??? -> • kSPrs_Stmt ???
// Aug 20, 1991
// If there is a comment following (which has IsSeparator() true),
// then the comment will cause the current context to be closed.
// This means that a statement of the form:
// if (…)
// …
// // …comment…
// else
// …
// will become a syntax error (or mis-format). But life's tough
// because the most common form for this pairing is for a statement
// sequence like:
// if (…)
// …
// // comment for the code following
// …
// which would otherwise have the comment indented more than it
// should be. This is a "shift-reduce" conflict, and the conflict
// is now being resolved by doing a reduce instead of a shift
if (aToken->Type() != kSLex_Comment && aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->CloseContext();
aParser->Reduce(&gPrsStmt, 3);
aParser->Parse(aToken);
break;
case 12: // ® kSLex_Context ")" kSLex_Context kSPrs_Stmt • "else" -> ® kSLex_Context ")" • kSPrs_Stmt "else"
aFormat->CloseContext();
aParser->Drop(2);
Accept(&gPrsStmt, aParser);
return (Accept(aToken, aParser));
case 13: // ® kSLex_Context kSLex_Context "(" kSPrs_Expr • "{" -> ® kSLex_Context ")" • "{"
aFormat->CloseContext();
aParser->Drop(3);
aParser->Shift(&gLexRParen);
return (Accept(aToken, aParser));
case 14: // ® kSLex_Context kSLex_Context "}" • "else" -> ® kSLex_Context ";" kSPrs_Else • "else"
aFormat->SetGlue(gFS_if6);
aFormat->Display(aParser->TopItem());
aFormat->CloseContext();
aParser->Drop(2);
aParser->Shift(&gLexSemiColon);
aParser->Shift(&gPrsElse);
aParser->Parse(aToken);
break;
case 15: // ® kSLex_Context kSLex_Context "}" • ??? -> ® kSLex_Context ";" • ???
if (aToken->Type() == kSLex_NewLine && !aFormat->PassSourceNewLines())
{
aParser->Shift(&gPrsNewLine);
return (true);
}
aFormat->SetGlue(gFS_if5);
aFormat->Display(aParser->TopItem());
aFormat->CloseContext();
aParser->Drop(2);
aParser->Shift(&gLexSemiColon);
return (Accept(aToken, aParser));
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_Else ( 6)
** ( 0) ® • "else" -> ® kSLex_Context "else" •
** ( 1) ® kSLex_Context "else" • "if" -> ® kSLex_Context "if" kSPrs_If • "if"
** ( 6) ® kSLex_Context "if" • kSPrs_Stmt -> • kSPrs_Else
** The "else" is not immediately displayed. It is deferred until the
** "if", "{" or ??? following it
**
** ( 2) ® kSLex_Context "else" • "{" -> ® kSLex_Context kSLex_Context "{" kSPrs_StmtList •
** ( 5) ® kSLex_Context kSLex_Context "{" kSPrs_StmtList • "}" -> • kSPrs_Else
**
** ( 3) ® kSLex_Context "else" • ??? -> ® kSLex_Context kSLex_Context kSPrs_Stmt • ???
** ( 4) ® kSLex_Context kSLex_Context • kSPrs_Stmt -> • kSPrs_Else
** Envelop the statement in its own context
**
** Handle the "else" clause of an if statement. First, display "else" (0).
** If the next token is an "if" (1), parse an if statement. If the token is
** a "{" (2), parse a statmentlist until the closing "}" (5). Otherwise,
** just do a single statement (3). When a statement has been parsed (4),
** reduce the else.
*/
#pragma segment ParserActions
Boolean
PrsElse::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
5, kSLex_RCurly, 5, kSPrs_Else, kSLex_Context, kSLex_Context, kSLex_LCurly, kSPrs_StmtList,
6, kSPrs_Stmt, 3, kSPrs_Else, kSLex_Context, kSLex_If,
1, kSLex_If, 3, kSPrs_Else, kSLex_Context, kSLex_Else,
2, kSLex_LCurly, 3, kSPrs_Else, kSLex_Context, kSLex_Else,
4, kSPrs_Stmt, 3, kSPrs_Else, kSLex_Context, kSLex_Context,
0, kSLex_Else, 1, kSPrs_Else,
3, -1, 3, kSPrs_Else, kSLex_Context, kSLex_Else,
-1, -1, 0
//ƒ+
};
short anIndex = aParser->FindHandle(aToken->Type(), handles);
DEBUGPARSER(Else, anIndex);
switch (anIndex)
{
case 0: // ® • "else" -> ® kSLex_Context "else" •
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aParser->Shift(&gContext);
aParser->Shift(aToken);
break;
case 1: // ® kSLex_Context "else" • "if" -> ® kSLex_Context "if" kSPrs_If • "if"
aFormat->SetGlue(gFS_else1);
aFormat->Display(aParser->TopItem());
aParser->TopItem(aToken);
aParser->Shift(&gPrsIf);
aParser->Parse(aToken);
break;
case 2: // ® kSLex_Context "else" • "{" -> ® kSLex_Context kSLex_Context "{" kSPrs_StmtList •
aFormat->OpenContext();
aFormat->SetGlue(gFS_else3);
aFormat->Display(aParser->TopItem());
aFormat->Display(aToken);
aParser->TopItem(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsStmtList);
break;
case 3: // ® kSLex_Context "else" • ??? -> ® kSLex_Context kSLex_Context kSPrs_Stmt • ???
// Explicitly disallow "else /*…*/ if", which is why there is no
// check for IsSeparator(). Otherwise, the comment would migrate
// before the "else"
if (aToken->Type() == kSLex_NewLine && !aFormat->PassSourceNewLines())
{
aParser->Shift(&gPrsNewLineIf);
return (true);
}
aFormat->OpenContext();
aFormat->SetGlue(gFS_else4);
aFormat->Display(aParser->TopItem());
aParser->TopItem(&gContext);
aParser->Shift(&gPrsStmt);
aParser->Parse(aToken);
break;
case 4: // ® kSLex_Context kSLex_Context • kSPrs_Stmt -> • kSPrs_Else
aFormat->CloseContext();
aFormat->CloseContext();
aParser->Reduce(&gPrsElse, 3);
break;
case 5: // ® kSLex_Context kSLex_Context "{" kSPrs_StmtList • "}" -> • kSPrs_Else
aFormat->SetGlue(gFS_else6);
aFormat->Display(aToken);
aFormat->CloseContext();
aFormat->CloseContext();
aParser->Reduce(&gPrsElse, 5);
break;
case 6: // ® kSLex_Context "if" • kSPrs_Stmt -> • kSPrs_Else
aFormat->CloseContext();
aParser->Reduce(&gPrsElse, 3);
break;
case 7: // ® kSLex_Context "else" • \n -> ® kSLex_Context "else" •
break;
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_For (10)
** ( 0) ® • "for" -> ® kSLex_Context •
** ( 1) ® kSLex_Context • "(" -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
** ( 2) ® kSLex_Context kSLex_Context "(" kSPrs_Expr • ";" -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
** ( 3) ® kSLex_Context kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
** ( 4) ® kSLex_Context kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_Context ")" •
** ( 9) ® kSLex_Context kSLex_Context "(" kSPrs_Expr • kSPrs_Decl -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
**
** ( 5) ® kSLex_Context ")" • "{" -> ® kSLex_Context "{" kSPrs_StmtList •
** (10) ® kSLex_Context ")" • ";" -> • kSPrs_Stmt
** ( 6) ® kSLex_Context ")" • ??? -> ® kSLex_Context kSPrs_Stmt • ???
**
** ( 7) ® kSLex_Context "{" kSPrs_StmtList • "}" -> • kSPrs_Stmt
**
** ( 8) ® kSLex_Context • kSPrs_Stmt -> • kSPrs_Stmt
**
** Recognize the "for" in (0) and then the "(" in (1). Parse the
** expression list, handling the ";" (2) and "," (3) until the closing
** ") in (4). Also handle initialization declarations (9) which consume
** the ";". If the token following the is a "{" (5) parse a statement
** list until the closing "} (7). Otherwise parse a single statment (8).
*/
#pragma segment ParserActions
Boolean
PrsFor::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
2, kSLex_SemiColon, 5, kSPrs_For, kSLex_Context, kSLex_Context, kSLex_LParen, kSPrs_Expr,
3, kSLex_Comma, 5, kSPrs_For, kSLex_Context, kSLex_Context, kSLex_LParen, kSPrs_Expr,
4, kSLex_RParen, 5, kSPrs_For, kSLex_Context, kSLex_Context, kSLex_LParen, kSPrs_Expr,
9, kSPrs_Decl, 5, kSPrs_For, kSLex_Context, kSLex_Context, kSLex_LParen, kSPrs_Expr,
7, kSLex_RCurly, 4, kSPrs_For, kSLex_Context, kSLex_LCurly, kSPrs_StmtList,
5, kSLex_LCurly, 3, kSPrs_For, kSLex_Context, kSLex_RParen,
10, kSLex_SemiColon, 3, kSPrs_For, kSLex_Context, kSLex_RParen,
1, kSLex_LParen, 2, kSPrs_For, kSLex_Context,
8, kSPrs_Stmt, 2, kSPrs_For, kSLex_Context,
0, kSLex_For, 1, kSPrs_For,
6, -1, 3, kSPrs_For, kSLex_Context, kSLex_RParen,
-1, -1, 0
//ƒ+
};
short anIndex = aParser->FindHandle(aToken->Type(), handles);
DEBUGPARSER(For, anIndex);
switch (anIndex)
{
case 0: // ® • "for" -> ® kSLex_Context •
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aFormat->SetGlue(gFS_for0);
aFormat->Display(aToken);
aParser->Shift(&gContext);
break;
case 1: // ® kSLex_Context • "(" -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
aFormat->OpenContext();
aFormat->SetGlue(gFS_for1);
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsExpr);
break;
case 2: // ® kSLex_Context kSLex_Context "(" kSPrs_Expr • ";" -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
aFormat->SetGlue(gFS_for3);
aFormat->Display(aToken);
break;
case 9: // ® kSLex_Context kSLex_Context "(" kSPrs_Expr • kSPrs_Decl -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
// Temporary hack: indicate that a new line has taken place.
aFormat->SetGlue((FormatString)"!n s#");
break;
case 3: // ® kSLex_Context kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
aFormat->Comma();
aFormat->Display(aToken);
break;
case 4: // ® kSLex_Context kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_Context ")" •
aFormat->SetGlue(gFS_for4);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(3);
aParser->Shift(aToken);
break;
case 5: // ® kSLex_Context ")" • "{" -> ® kSLex_Context "{" kSPrs_StmtList •
aFormat->SetGlue(gFS_for5);
aFormat->Display(aToken);
aParser->TopItem(aToken);
aParser->Shift(&gPrsStmtList);
break;
case 10: // ® kSLex_Context ")" • ";" -> • kSPrs_Stmt
aFormat->SetGlue(gFS_for6);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Reduce(&gPrsStmt, 3);
break;
case 6: // ® kSLex_Context ")" • ??? -> ® kSLex_Context kSPrs_Stmt • ???
if (aToken->Type() == kSLex_NewLine && !aFormat->PassSourceNewLines())
{
aParser->Shift(&gPrsNewLine);
return (true);
}
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->SetGlue(gFS_for7);
aParser->TopItem(&gPrsStmt);
aParser->Parse(aToken);
break;
case 7: // ® kSLex_Context "{" kSPrs_StmtList • "}" -> • kSPrs_Stmt
aFormat->SetGlue(gFS_for8);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Reduce(&gPrsStmt, 4);
break;
case 8: // ® kSLex_Context • kSPrs_Stmt -> • kSPrs_Stmt
aFormat->CloseContext();
aParser->Reduce(&gPrsStmt, 2);
break;
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_Struct (18)
** ( 0) ® • "struct" -> ® kSLex_Context •
** Recognize the word "struct" and emit it. The word is not emitted until
** a later time.
**
** ( 1) ® kSLex_Context • "{" -> ® kSLex_Context "{" kSPrs_DeclList •
** (16) ® kSLex_Context "{" kSPrs_DeclList • "," -> ® kSLex_Context "{" kSPrs_DeclList •
** ( 2) ® kSLex_Context "{" kSPrs_DeclList • "}" -> ® kSLex_Context "{" "}" •
** (17) ® kSLex_Context "{" "}" • ";" -> • kSPrs_Decl
** (18) ® kSLex_Context "{" "}" • ??? -> • kSPrs_DeclType ???
** When the opening curly is found, enter the body of the struct. Then
** body is a declaration list. When the closing curly is found, emit the
** kSPrs_DeclType. A comma in the middle of the list is usually because
** the struct is an enum
**
** ( 3) ? • kSLex_Public -> ? kSLex_Public •
** ( 4) ? KSLex_Public • ":" -> ? •
** ( 5) ? KSLex_Public • ??? -> ? • ???
** Within the body of a struct the "public" keywords are allowed. They
** are followed by ":" and have no other effect. We delay the display
** of the word public until we know that this is a C++ public declaration
** and not the name of a field (for example).
**
** ( 6) ® kSLex_Context • kSLex_ParsedId -> ® kSLex_Context kSLex_ParsedId •
** ( 7) ® kSLex_Context kSLex_ParsedId • "{" -> ® kSLex_Context "{" kSPrs_DeclList •
** ( 8) ® kSLex_Context kSLex_ParsedId • ":" -> ® kSLex_Context kSLex_ParsedId ":" •
** ( 9) ® kSLex_Context kSLex_ParsedId • ??? -> • kSPrs_DeclType ???
** A "struct" can also be followed by a name and optional inheritance
** information. This state is denoted by "® kSLex_ParsedId •". When
** followed by "{", it devolves into the unnamed struct declaration list
** mentioned above. When followed by a ":", inheritance information must
** be parsed ("® kSLex_ParsedId ":" •"). Otherwise, reduce it to a
** kSPrs_DeclType and pass the extra token upstairs.
**
** (10) ® kSLex_Context kSLex_ParsedId ":" • kSLex_ParsedId -> ® kSLex_Context kSLex_ParsedId ":" •
** (11) ® kSLex_Context kSLex_ParsedId ":" • kSLex_Public -> ® kSLex_Context kSLex_ParsedId ":" •
** (12) ® kSLex_Context kSLex_ParsedId ":" • kSLex_Decl -> ® kSLex_Context kSLex_ParsedId ":" •
** (13) ® kSLex_Context kSLex_ParsedId ":" • "," -> ® kSLex_Context kSLex_ParsedId ":" •
** (14) ® kSLex_Context kSLex_ParsedId ":" • ??? -> ® kSLex_Context kSLex_ParsedId • ???
** Inheritance information is a bunch of comma separated "public", types
** and identifiers. Anything else (such as "{") reduces to a named
** struct ("® kSLex_ParsedId •") and is processed that way.
**
** (15) ® kSLex_Context • ??? -> • kSPrs_DeclType ???
** If the word "struct" is followed by anything unexpected, reduce it
** to a DeclType and pass the token following it upstairs.
*/
#pragma segment ParserActions
Boolean
PrsStruct::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
2, kSLex_RCurly, 4, kSPrs_Struct, kSLex_Context, kSLex_LCurly, kSPrs_DeclList,
16, kSLex_Comma, 4, kSPrs_Struct, kSLex_Context, kSLex_LCurly, kSPrs_DeclList,
17, kSLex_SemiColon, 4, kSPrs_Struct, kSLex_Context, kSLex_LCurly, kSLex_RCurly,
10, kSLex_ParsedId, 4, kSPrs_Struct, kSLex_Context, kSLex_ParsedId, kSLex_Colon,
11, kSLex_Public, 4, kSPrs_Struct, kSLex_Context, kSLex_ParsedId, kSLex_Colon,
12, kSLex_Decl, 4, kSPrs_Struct, kSLex_Context, kSLex_ParsedId, kSLex_Colon,
13, kSLex_Comma, 4, kSPrs_Struct, kSLex_Context, kSLex_ParsedId, kSLex_Colon,
7, kSLex_LCurly, 3, kSPrs_Struct, kSLex_Context, kSLex_ParsedId,
8, kSLex_Colon, 3, kSPrs_Struct, kSLex_Context, kSLex_ParsedId,
1, kSLex_LCurly, 2, kSPrs_Struct, kSLex_Context,
6, kSLex_ParsedId, 2, kSPrs_Struct, kSLex_Context,
0, kSLex_Struct, 1, kSPrs_Struct,
4, kSLex_Colon, 1, kSLex_Public,
3, kSLex_Public, 0,
18, -1, 4, kSPrs_Struct, kSLex_Context, kSLex_LCurly, kSLex_RCurly,
14, -1, 4, kSPrs_Struct, kSLex_Context, kSLex_ParsedId, kSLex_Colon,
9, -1, 3, kSPrs_Struct, kSLex_Context, kSLex_ParsedId,
15, -1, 2, kSPrs_Struct, kSLex_Context,
5, -1, 1, kSLex_Public,
-1, -1, 0
//ƒ+
};
short anIndex = aParser->FindHandle(aToken->Type(), handles);
DEBUGPARSER(Struct, anIndex);
switch (anIndex)
{
case 0: // ® • "struct" -> ® kSLex_Context •
aFormat->OpenContext();
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aFormat->SetGlue(gFS_struct0);
aFormat->Display(aToken);
aParser->Shift(&gContext);
break;
case 1: // ® kSLex_Context • "{" -> ® kSLex_Context "{" kSPrs_DeclList •
aFormat->SetGlue(gFS_struct3);
aFormat->Display(aToken);
aParser->Shift(aToken);
aParser->Shift(&gPrsDeclList);
break;
case 2: // ® kSLex_Context "{" kSPrs_DeclList • "}" -> ® kSLex_Context "{" "}" •
aFormat->SetGlue(gFS_struct6);
aFormat->Display(aToken);
aParser->TopItem(aToken);
break;
case 3: // ? • kSLex_Public -> ? kSLex_Public •
aParser->Shift(aToken);
break;
case 4: // ? KSLex_Public • ":" -> ? •
aFormat->SetGlue(gFS_struct5);
aFormat->Display(aParser->TopItem());
aFormat->Display(aToken);
aParser->Drop(1);
break;
case 5: // ? KSLex_Public • ??? -> ? • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aParser->Reduce(new PrsAsId(aParser->TopItem()), 1);
return (aParser->Parse(aToken));
case 6: // ® kSLex_Context • kSLex_ParsedId -> ® kSLex_Context kSLex_ParsedId •
aFormat->Name();
aFormat->Display(aToken);
aParser->Shift(aToken);
break;
case 7: // ® kSLex_Context kSLex_ParsedId • "{" -> ® kSLex_Context "{" kSPrs_DeclList •
aFormat->RestoreIndent();
aFormat->SetGlue(gFS_struct3);
aFormat->Display(aToken);
aParser->TopItem(aToken);
aParser->Shift(&gPrsDeclList);
break;
case 8: // ® kSLex_Context kSLex_ParsedId • ":" -> ® kSLex_Context kSLex_ParsedId ":" •
aFormat->SetGlue(gFS_struct1);
aFormat->Display(aToken);
aParser->Shift(aToken);
break;
case 9: // ® kSLex_Context kSLex_ParsedId • ??? -> • kSPrs_DeclType ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->CloseContext();
aParser->Reduce(&gPrsDeclType, 3);
return (aParser->Parse(aToken));
case 10: // ® kSLex_Context kSLex_ParsedId ":" • kSLex_ParsedId -> ® kSLex_Context kSLex_ParsedId ":" •
case 11: // ® kSLex_Context kSLex_ParsedId ":" • kSLex_Public -> ® kSLex_Context kSLex_ParsedId ":" •
case 12: // ® kSLex_Context kSLex_ParsedId ":" • kSLex_Decl -> ® kSLex_Context kSLex_ParsedId ":" •
aFormat->Name();
aFormat->Display(aToken);
break;
case 13: // ® kSLex_Context kSLex_ParsedId ":" • "," -> ® kSLex_Context kSLex_ParsedId ":" •
aFormat->SetGlue(gFS_struct2);
aFormat->Display(aToken);
break;
case 14: // ® kSLex_Context kSLex_ParsedId ":" • ??? -> ® kSLex_Context kSLex_ParsedId • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->RestoreIndent();
aParser->Drop(1);
return (Accept(aToken, aParser));
case 15: // ® kSLex_Context • ??? -> • kSPrs_DeclType ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->CloseContext();
aParser->Reduce(&gPrsDeclType, 2);
return (aParser->Parse(aToken));
case 16: // ® kSLex_Context "{" kSPrs_DeclList • "," -> ® kSLex_Context "{" kSPrs_DeclList •
aFormat->Comma();
aFormat->Display(aToken);
break;
case 17: // ® kSLex_Context "{" "}" • ";" -> • kSPrs_Decl
aFormat->SetGlue(gFS_struct7);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Reduce(&gPrsDecl, 4);
break;
case 18: // ® kSLex_Context "{" "}" • ??? -> • kSPrs_DeclType ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aFormat->CloseContext();
aParser->Reduce(&gPrsDeclType, 4);
return (aParser->Parse(aToken));
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_Switch ( 8)
** ( 0) ® • "switch" -> ® kSLex_Context •
** ( 1) ® kSLex_Context • "(" -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
** ( 2) ® kSLex_Context kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
** ( 3) ® kSLex_Context kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_Context ")" •
**
** ( 4) ® kSLex_Context ")" • "{" -> ® kSLex_Context "{" kSPrs_StmtList •
** ( 5) ® kSLex_Context "{" kSPrs_StmtList • "}" -> • kSPrs_Stmt
**
** ( 6) ? • "case" -> ? "case" kSPrs_Expr •
** ( 7) ? • "default" -> ? "case" kSPrs_Expr •
** ( 8) ? "case" kSPrs_Expr • ":" -> ? •
**
** The "switch" is followed by a "(<expr>)", (0, 1, 2). The body of the
** switch is bracketed by "{..}". The opening is recognized by (3). At
** that point, a statement list is recognized (4..6), with the addition of
** "case" (4) and "default" (5). Parsing of the statement list does not
** resume until the closing ":" for the case/default has been recognized
** done by (7) and (8). Note that states (4) and (5) are not in the list
** of handles as Parser::FindHandle() does not have a syntax for arbitrary
** right hand side and it is not known what kSPrs_StmtList might have on the
** parse stack at the time.
*/
#pragma segment ParserActions
Boolean
PrsSwitch::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
2, kSLex_Comma, 5, kSPrs_Switch, kSLex_Context, kSLex_Context, kSLex_LParen, kSPrs_Expr,
3, kSLex_RParen, 5, kSPrs_Switch, kSLex_Context, kSLex_Context, kSLex_LParen, kSPrs_Expr,
5, kSLex_RCurly, 4, kSPrs_Switch, kSLex_Context, kSLex_LCurly, kSPrs_StmtList,
4, kSLex_LCurly, 3, kSPrs_Switch, kSLex_Context, kSLex_RParen,
1, kSLex_LParen, 2, kSPrs_Switch, kSLex_Context,
8, kSLex_Colon, 2, kSLex_Case, kSPrs_Expr,
0, kSLex_Switch, 1, kSPrs_Switch,
6, kSLex_Case, 0,
7, kSLex_Default, 0,
-1, -1, 0
//ƒ+
};
short anIndex = aParser->FindHandle(aToken->Type(), handles);
DEBUGPARSER(Switch, anIndex);
switch (anIndex)
{
case 0: // ® • "switch" -> ® kSLex_Context •
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aFormat->SetGlue(gFS_switch0);
aFormat->Display(aToken);
aParser->Shift(&gContext);
break;
case 1: // ® kSLex_Context • "(" -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
aFormat->OpenContext();
aFormat->SetGlue(gFS_switch1);
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsExpr);
break;
case 2: // ® kSLex_Context kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
aFormat->Comma();
aFormat->Display(aToken);
break;
case 3: // ® kSLex_Context kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_Context ")" •
aFormat->RParen();
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(3);
aParser->Shift(aToken);
break;
case 4: // ® kSLex_Context ")" • "{" -> ® kSLex_Context "{" kSPrs_StmtList •
aFormat->SetGlue(gFS_switch2);
aFormat->Display(aToken);
aParser->TopItem(aToken);
aParser->Shift(&gPrsStmtList);
break;
case 5: // ® kSLex_Context "{" kSPrs_StmtList • "}" -> • kSPrs_Stmt
aFormat->SetGlue(gFS_switch7);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Reduce(&gPrsStmt, 4);
break;
case 6: // ? • "case" -> ? "case" kSPrs_Expr •
case 7: // ? • "default" -> ? "case" kSPrs_Expr •
aFormat->SetGlue(aToken->Type() == kSLex_Case ? gFS_switch3 : gFS_switch4);
aFormat->Display(aToken);
aParser->Shift(&gLexCase);
aParser->Shift(&gPrsExpr);
break;
case 8: // ? "case" kSPrs_Expr • ":" -> ? •
aFormat->SetGlue(gFS_switch5);
aFormat->Display(aToken);
aParser->Drop(2);
break;
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_While ( 8)
** ( 0) ® • "while" -> ® kSLex_Context •
** ( 2) ® kSLex_Context • "(" -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
** ( 8) ® kSLex_Context kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
** ( 3) ® kSLex_Context kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_Context ")" •
**
** ( 4) ® kSLex_Context ")" • "{" -> ® kSLex_Context "{" kSPrs_StmtList •
** ( 7) ® kSLex_Context "{" kSPrs_StmtList • "}" -> • kSPrs_Stmt
**
** ( 5) ® kSLex_Context ")" • ";" -> • kSPrs_Stmt
**
** ( 6) ® kSLex_Context ")" • ??? -> ® kSLex_Context kSPrs_Stmt • ???
** ( 1) ® kSLex_Context • kSPrs_Stmt -> • kSPrs_Stmt
**
**
** The "while" is followed by a "(...)", handled by (0, 2, 3) and then
** a statement. The statement can be a ";", handled by (5), a "{...}",
** handled by (4, 7), or some other statement, handled by (6, 1)
*/
#pragma segment ParserActions
Boolean
PrsWhile::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
3, kSLex_RParen, 5, kSPrs_While, kSLex_Context, kSLex_Context, kSLex_LParen, kSPrs_Expr,
8, kSLex_Comma, 5, kSPrs_While, kSLex_Context, kSLex_Context, kSLex_LParen, kSPrs_Expr,
7, kSLex_RCurly, 4, kSPrs_While, kSLex_Context, kSLex_LCurly, kSPrs_StmtList,
4, kSLex_LCurly, 3, kSPrs_While, kSLex_Context, kSLex_RParen,
5, kSLex_SemiColon, 3, kSPrs_While, kSLex_Context, kSLex_RParen,
1, kSPrs_Stmt, 2, kSPrs_While, kSLex_Context,
2, kSLex_LParen, 2, kSPrs_While, kSLex_Context,
0, kSLex_While, 1, kSPrs_While,
6, -1, 3, kSPrs_While, kSLex_Context, kSLex_RParen,
-1, -1, 0
//ƒ+
};
short anIndex = aParser->FindHandle(aToken->Type(), handles);
DEBUGPARSER(While, anIndex);
switch (anIndex)
{
case 0: // ® • "while" -> ® kSLex_Context •
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aFormat->SetGlue(gFS_while0);
aFormat->Display(aToken);
aParser->Shift(&gContext);
break;
case 1: // ® kSLex_Context • kSPrs_Stmt -> • kSPrs_Stmt
aFormat->CloseContext();
aParser->Reduce(aToken, 2);
break;
case 2: // ® kSLex_Context • "(" -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
aFormat->OpenContext();
aFormat->SetGlue(gFS_while1);
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsExpr);
break;
case 3: // ® kSLex_Context kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_Context ")" •
aFormat->SetGlue(gFS_while6);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(3);
aParser->Shift(aToken);
break;
case 8: // ® kSLex_Context kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_Context kSLex_Context "(" kSPrs_Expr •
aFormat->Comma();
aFormat->Display(aToken);
break;
case 4: // ® kSLex_Context ")" • "{" -> ® kSLex_Context "{" kSPrs_StmtList •
aFormat->SetGlue(gFS_while2);
aFormat->Display(aToken);
aParser->TopItem(aToken);
aParser->Shift(&gPrsStmtList);
break;
case 5: // ® kSLex_Context ")" • ";" -> • kSPrs_Stmt
aFormat->SetGlue(gFS_while3);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Reduce(&gPrsStmt, 3);
break;
case 6: // ® kSLex_Context ")" • ??? -> ® kSLex_Context kSPrs_Stmt • ???
if (aToken->Type() == kSLex_NewLine && !aFormat->PassSourceNewLines())
{
aParser->Shift(&gPrsNewLine);
return (true);
}
aFormat->SetGlue(gFS_while4);
aParser->TopItem(&gPrsStmt);
aParser->Parse(aToken);
break;
case 7: // ® kSLex_Context "{" kSPrs_StmtList • "}" -> • kSPrs_Stmt
aFormat->SetGlue(gFS_while5);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Reduce(&gPrsStmt, 4);
break;
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_Expr (36)
** ( 0) ® • "(" -> ® kSLex_Context "(" kSPrs_Expr •
** (34) ? • "(" -> ? kSPrs_Expr • "("
** ( 8) ® kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_ParsedId •
** ( 9) ® kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_Context "(" kSPrs_Expr •
** A "(" is ambiguous. It can be a cast or the beginning of an expression.
** consequently, wait for the next token, which can be a declaration
** word, in which case we assume it's a cast, or a anything else, which
** makes it an expression.
**
** ( 1) ® • "[" -> ® kSLex_Context "[" kSPrs_Expr •
** (10) ® kSLex_Context "[" kSPrs_Expr • "]" -> ® kSLex_ParsedId •
** (11) ® kSLex_Context "[" kSPrs_Expr • "," -> ® kSLex_Context "[" •
** A bracketed expression might have commas in it. Handle it. Reduce
** to the base state when the close brace comes.
**
** ( 3) ® • kSLex_Op -> ® kSLex_Op •
** (12) ® kSLex_Op • "(" -> ® • "("
** (26) ® kSLex_Op • "[" -> ® • "["
** (13) ® kSLex_Op • kSLex_Op -> ® kSLex_Op •
** (14) ® kSLex_Op • kSLex_ParsedId -> ® kSLex_ParsedId •
** (15) ® kSLex_Op • "struct" -> ® kSPrs_Decl • "struct"
** (16) ® kSLex_Op • kSLex_Value -> ® kSLex_ParsedId •
** (17) ® kSLex_Op • kSLex_Ellipsis -> ® kSLex_ParsedId •
** (18) ® kSLex_Op • ??? -> ® • ???
**
** (32) ® • "?" -> ® kSLex_Context "?" kSPrs_Expr •
** (28) ® kSLex_Context "?" kSPrs_Expr • ":" -> ® •
** (31) ® kSLex_Context "?" kSPrs_Expr • "," -> ® kSLex_Context "?" kSPrs_Expr •
** Conditional expressions can have commas in the true part. Handle
** them.
**
** ( 2) ® • "struct" -> ® kSPrs_Decl • "struct"
** (35) ® • kSLex_Decl -> ® kSPrs_Decl • kSLex_Decl
** (33) ® kSPrs_Decl • ??? -> ® • ???
** When a declarative entity returns, return to normal operation.
**
** ( 4) ® • kSLex_ParsedId -> ® kSLex_ParsedId •
** ( 5) ® • kSPrs_DeclType -> ® kSLex_ParsedId •
** ( 6) ® • kSLex_Value -> ® kSLex_ParsedId •
** ( 7) ® • kSLex_Ellipsis -> ® kSLex_ParsedId •
** (27) ® kSLex_ParsedId • "[" -> ® • "["
** (20) ® kSLex_ParsedId • kSLex_Op -> ® kSLex_Op •
** (21) ® kSLex_ParsedId • kSLex_ParsedId -> ® kSLex_ParsedId •
** (22) ® kSLex_ParsedId • "struct" -> ® • "struct"
** (23) ® kSLex_ParsedId • kSLex_Value -> ® kSLex_ParsedId •
** (24) ® kSLex_ParsedId • kSLex_Ellipsis -> ® kSLex_ParsedId •
**
** (19) ® kSLex_ParsedId • "(" -> ® kSLex_ParsedId kSLex_Context "(" kSPrs_Expr •
** (29) ® kSLex_ParsedId kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_ParsedId kSLex_Context "(" kSPrs_Expr •
** (36) ® kSLex_ParsedId kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_ParsedId •
**
** (25) ® kSLex_ParsedId • ??? -> ® • ???
**
** An expression is a pile of symbols with balanced brackets. Spaces are
** inserted between id-like things, hence the kSLex_ParsedId entries saved on the
** stack. An expression never terminates: it remains on the stack consuming
** valid tokens until someone else removes it.
*/
#pragma segment ParserActions
Boolean
PrsExpr::Accept(Syntactic* aToken, Parser* aParser)
{
Formatting* aFormat = aParser->GetFormatting();
static const short handles[] =
{
//ƒ-
29, kSLex_Comma, 5, kSPrs_Expr, kSLex_ParsedId, kSLex_Context, kSLex_LParen, kSPrs_Expr,
36, kSLex_RParen, 5, kSPrs_Expr, kSLex_ParsedId, kSLex_Context, kSLex_LParen, kSPrs_Expr,
8, kSLex_RParen, 4, kSPrs_Expr, kSLex_Context, kSLex_LParen, kSPrs_Expr,
9, kSLex_Comma, 4, kSPrs_Expr, kSLex_Context, kSLex_LParen, kSPrs_Expr,
10, kSLex_RBrace, 4, kSPrs_Expr, kSLex_Context, kSLex_LBrace, kSPrs_Expr,
11, kSLex_Comma, 4, kSPrs_Expr, kSLex_Context, kSLex_LBrace, kSPrs_Expr,
28, kSLex_Colon, 4, kSPrs_Expr, kSLex_Context, kSLex_OpQuestion, kSPrs_Expr,
31, kSLex_Comma, 4, kSPrs_Expr, kSLex_Context, kSLex_OpQuestion, kSPrs_Expr,
12, kSLex_LParen, 2, kSPrs_Expr, kSLex_Op,
26, kSLex_LBrace, 2, kSPrs_Expr, kSLex_Op,
13, kSLex_Op, 2, kSPrs_Expr, kSLex_Op,
14, kSLex_ParsedId, 2, kSPrs_Expr, kSLex_Op,
15, kSLex_Struct, 2, kSPrs_Expr, kSLex_Op,
16, kSLex_Value, 2, kSPrs_Expr, kSLex_Op,
17, kSLex_Ellipsis, 2, kSPrs_Expr, kSLex_Op,
19, kSLex_LParen, 2, kSPrs_Expr, kSLex_ParsedId,
27, kSLex_LBrace, 2, kSPrs_Expr, kSLex_ParsedId,
20, kSLex_Op, 2, kSPrs_Expr, kSLex_ParsedId,
21, kSLex_ParsedId, 2, kSPrs_Expr, kSLex_ParsedId,
22, kSLex_Struct, 2, kSPrs_Expr, kSLex_ParsedId,
23, kSLex_Value, 2, kSPrs_Expr, kSLex_ParsedId,
24, kSLex_Ellipsis, 2, kSPrs_Expr, kSLex_ParsedId,
0, kSLex_LParen, 1, kSPrs_Expr,
1, kSLex_LBrace, 1, kSPrs_Expr,
2, kSLex_Struct, 1, kSPrs_Expr,
35, kSLex_Decl, 1, kSPrs_Expr,
3, kSLex_Op, 1, kSPrs_Expr,
// 32, kSLex_OpQuestion, 1, kSPrs_Expr,
4, kSLex_ParsedId, 1, kSPrs_Expr,
5, kSPrs_DeclType, 1, kSPrs_Expr,
6, kSLex_Value, 1, kSPrs_Expr,
7, kSLex_Ellipsis, 1, kSPrs_Expr,
34, kSLex_LParen, 0,
18, -1, 2, kSPrs_Expr, kSLex_Op,
25, -1, 2, kSPrs_Expr, kSLex_ParsedId,
33, -1, 2, kSPrs_Expr, kSPrs_Decl,
-1, -1, 0
//ƒ+
};
/*
** Hack. Various states are hidden under other states.
**
** (3) -> (32)
** The operator might a "?", part of a destructor name.
*/
short anIndex = aParser->FindHandle(aToken->Type(), handles);
switch (anIndex)
{
case 3:
if (aToken->MinorType() == kSLex_OpQuestion)
anIndex = 32;
break;
}
DEBUGPARSER(Expr, anIndex);
switch (anIndex)
{
case 0: // ® • "(" -> ® kSLex_Context "(" kSPrs_Expr •
case 1: // ® • "[" -> ® kSLex_Context "[" kSPrs_Expr •
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aFormat->LParen();
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsExpr);
break;
case 34: // ? • "(" -> ? kSPrs_Expr • "("
aParser->Shift(&gPrsExpr);
aParser->Parse(aToken);
break;
case 2: // ® • "struct" -> ® kSPrs_Decl • "struct"
case 35: // ® • kSLex_Decl -> ® kSPrs_Decl • kSLex_Decl
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aFormat->SetGlue((FormatString)"&n"); // Don't newline
aParser->Shift(&gPrsDecl);
aParser->Parse(aToken);
break;
case 33: // ® kSPrs_Decl • ??? -> ® • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aParser->Drop(1);
return (Accept(aToken, aParser));
case 3: // ® • kSLex_Op -> ® kSLex_Op •
//aFormat->Operator();
aFormat->Display(aToken);
aParser->Shift(aToken);
break;
case 4: // ® • kSLex_ParsedId -> ® kSLex_ParsedId •
case 5: // ® • kSPrs_DeclType -> ® kSLex_ParsedId •
case 6: // ® • kSLex_Value -> ® kSLex_ParsedId •
case 7: // ® • kSLex_Ellipsis -> ® kSLex_ParsedId •
aFormat->Name();
aFormat->Display(aToken);
aParser->Shift(&gLexParsedId);
break;
case 8: // ® kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_ParsedId •
case 10: // ® kSLex_Context "[" kSPrs_Expr • "]" -> ® kSLex_ParsedId •
aFormat->RParen();
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(3);
aParser->Shift(&gLexParsedId);
break;
case 9: // ® kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_Context "(" kSPrs_Expr •
case 11: // ® kSLex_Context "[" kSPrs_Expr • "," -> ® kSLex_Context "[" kSPrs_Expr •
case 31: // ® kSLex_Context "?" kSPrs_Expr • "," -> ® kSLex_Context "?" kSPrs_Expr •
aFormat->Comma();
aFormat->Display(aToken);
break;
case 32: // ® • "?" -> ® kSLex_Context "?" kSPrs_Expr •
aFormat->OpenContext();
DEBUGSETCONTEXT(setExprContext)
setExprContext(aFormat);
aFormat->SetGlue(gFS_expr2);
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(&gLexQuestion);
aParser->Shift(&gPrsExpr);
break;
case 28: // ® kSLex_Context "?" kSPrs_Expr • ":" -> ® •
aFormat->SetGlue(gFS_expr3);
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(3);
break;
case 12: // ® kSLex_Op • "(" -> ® • "("
case 26: // ® kSLex_Op • "[" -> ® • "["
aParser->Drop(1);
return (Accept(aToken, aParser));
case 15: // ® kSLex_Op • kSLex_Struct -> ® kSPrs_Struct • "struct"
case 22: // ® kSLex_ParsedId • kSLex_Struct -> ® kSPrs_Struct • "struct"
aFormat->Name();
aFormat->SetGlue((FormatString)"&n"); // Don't newline
DEBUGSETCONTEXT(setDeclContext)
setDeclContext(aFormat);
aParser->TopItem(&gPrsDecl);
aParser->Parse(aToken);
break;
case 14: // ® kSLex_Op • kSLex_ParsedId -> ® kSLex_ParsedId •
case 16: // ® kSLex_Op • kSLex_Value -> ® kSLex_ParsedId •
case 17: // ® kSLex_Op • kSLex_Ellipsis -> ® kSLex_ParsedId •
aFormat->Name();
aFormat->Display(aToken);
aParser->TopItem(&gLexParsedId);
break;
case 18: // ® kSLex_Op • ??? -> ® • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aParser->Drop(1);
return (Accept(aToken, aParser));
case 25: // ® kSLex_ParsedId • ??? -> ® • ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aParser->Drop(1);
return (Accept(aToken, aParser));
case 19: // ® kSLex_ParsedId • "(" -> ® kSLex_ParsedId kSLex_Context "(" kSPrs_Expr •
aFormat->OpenContext();
DEBUGSETCONTEXT(setFuncallContext)
setFuncallContext(aFormat);
aFormat->LParen();
aFormat->Display(aToken);
aParser->Shift(&gContext);
aParser->Shift(aToken);
aParser->Shift(&gPrsExpr);
break;
case 29: // ® kSLex_ParsedId kSLex_Context "(" kSPrs_Expr • "," -> ® kSLex_ParsedId kSLex_Context "(" kSPrs_Expr •
aFormat->Comma();
aFormat->Display(aToken);
break;
case 36: // ® kSLex_ParsedId kSLex_Context "(" kSPrs_Expr • ")" -> ® kSLex_ParsedId •
aFormat->RParen();
aFormat->Display(aToken);
aFormat->CloseContext();
aParser->Drop(3);
break;
case 13: // ® kSLex_Op • kSLex_Op -> ® kSLex_Op •
case 20: // ® kSLex_ParsedId • kSLex_Op -> ® kSLex_Op •
// This is not a prefix operator. Consequently we apply the
// operator glue. However, some operators are always adjoined
// to their left hand side: postfix incrementors and member
// qualifiers. Don't use operator glue for these.
switch (aToken->MinorType())
{
case kSLex_OpClassStar:
case kSLex_OpDotStar:
case kSLex_OpPointerStar:
case kSLex_OpDot:
case kSLex_OpPointer:
// The only glue for these is none. No spaces between this
// operator and what was on the left of it.
aFormat->SetGlue((FormatString)"!s");
break;
case kSLex_OpPlusPlus:
case kSLex_OpMinusMinus:
{
Syntactic* topItem = aParser->TopItem();
// Make sure that these operators are not transformed into
// something wrong: "- --x" should not become "---x". We are
// cheesy here: "-++x" becomes "- ++x" even though it doesn't
// have to.
if (topItem->MinorType() == kSLex_OpAdd || topItem->MinorType() == kSLex_OpSub)
aFormat->SetGlue((FormatString)"?n{}{&s}•");
else
aFormat->SetGlue((FormatString)"!s");
}
break;
case kSLex_OpAssign:
case kSLex_OpAssignMul:
case kSLex_OpAssignDiv:
case kSLex_OpAssignMod:
case kSLex_OpAssignAdd:
case kSLex_OpAssignSub:
case kSLex_OpAssignRSh:
case kSLex_OpAssignLSh:
case kSLex_OpAssignBAnd:
case kSLex_OpAssignBXor:
case kSLex_OpAssignBOr:
// This is an assignment operator. Apply the assignment operator
// glue to the format.
aFormat->Assign();
break;
case kSLex_OpQuestion:
// Handle the question operator
aParser->Drop(1);
return (Accept(aToken, aParser));
default:
{
Syntactic* topItem = aParser->TopItem();
// If the previous item was an operator and not ++ or --, then this
// is a unary operator. Emit glue for it as such.
if (topItem->Type() == kSLex_Op &&
topItem->MinorType() != kSLex_OpPlusPlus &&
topItem->MinorType() != kSLex_OpMinusMinus)
{
Boolean isSpecialUnary = false;
// Compare the previous operator with this current operator.
// It behooves us to emit a blank to avoid changing "- -x"
// into "--x", a totally different statement. If this is the case,
// require a blank by emitting glue to that effect.
switch (aToken->MinorType())
{
case kSLex_OpAdd:
case kSLex_OpSub:
isSpecialUnary = (topItem->MinorType() == aToken->MinorType());
break;
}
if (isSpecialUnary)
aFormat->SetGlue((FormatString)"?n{}{&s}•");
else
aFormat->SetGlue((FormatString)"•!s");
}
else
aFormat->Operator();
break;
}
}
aFormat->Display(aToken);
aParser->TopItem(aToken);
break;
case 27: // ® kSLex_ParsedId • "[" -> ® • "["
aParser->Drop(1);
return (Accept(aToken, aParser));
case 21: // ® kSLex_ParsedId • kSLex_ParsedId -> ® kSLex_ParsedId •
case 23: // ® kSLex_ParsedId • kSLex_Value -> ® kSLex_ParsedId •
case 24: // ® kSLex_ParsedId • kSLex_Ellipsis -> ® kSLex_ParsedId •
aFormat->Name();
aFormat->Display(aToken);
break;
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_DeclOperator ( 9)
** ( 0) ? ® • "operator" -> "operator" ® •
** ( 1) ? "operator" ® • kSLex_Id -> • kSLex_Id
** ( 2) ? "operator" ® • kSLex_Op -> • kSLex_Id
** ( 3) ? "operator" ® • "(" -> ? "operator" "(" ® •
** ( 4) ? "operator" ® • "[" -> ? "operator" "[" ® •
** ( 5) ? "operator" "(" ® • ")" -> • kSLex_Id
** ( 6) ? "operator" "[" ® • "]" -> • kSLex_Id
** ( 7) ? "operator" "(" ® • ??? -> ? • kSLex_ParsedId "(" ???
** ( 8) ? "operator" "[" ® • ??? -> ? • kSLex_ParsedId "[" ???
** ( 9) ? "operator" ® • ??? -> ? • kSLex_ParsedId ???
** Parse the phrase "operator". When done, it has changed its sex into
** kSLex_Id and can be used anywhere that a kSLex_Id can be used. The
** states where an error might be possible will be assumed to result in the
** identifier "operator" being parsed and the tokens following to be sent
** along.
*/
#pragma segment ParserActions
Boolean
PrsDeclOperator::Accept(Syntactic *aToken, Parser *aParser)
{
Formatting * aFormat = aParser->GetFormatting();
static const short handles[] = {
//ƒ-
5, kSLex_RParen, 3, kSLex_DeclOperator, kSLex_LParen, kSPrs_DeclOperator,
6, kSLex_RBrace, 3, kSLex_DeclOperator, kSLex_LBrace, kSPrs_DeclOperator,
1, kSLex_Id, 2, kSLex_DeclOperator, kSPrs_DeclOperator,
2, kSLex_Op, 2, kSLex_DeclOperator, kSPrs_DeclOperator,
3, kSLex_LParen, 2, kSLex_DeclOperator, kSPrs_DeclOperator,
4, kSLex_LBrace, 2, kSLex_DeclOperator, kSPrs_DeclOperator,
0, kSLex_DeclOperator, 1, kSPrs_DeclOperator,
7, -1, 3, kSLex_DeclOperator, kSLex_LParen, kSPrs_DeclOperator,
8, -1, 3, kSLex_DeclOperator, kSLex_LBrace, kSPrs_DeclOperator,
9, -1, 2, kSLex_DeclOperator, kSPrs_DeclOperator,
-1, -1, 0
//ƒ+
};
short anIndex = aParser->FindHandle(aToken->Type(), handles);
switch (anIndex)
{
case 0: // ? ® • "operator" -> "operator" ® •
aParser->TopItem(aToken);
aParser->Shift(this);
break;
case 1: // ? "operator" ® • kSLex_Id -> • kSLex_Id
case 2: // ? "operator" ® • kSLex_Op -> • kSLex_Id
fToken = aToken;
SexChange(kSLex_Id);
aParser->Reduce(this, 2);
break;
case 3: // ? "operator" ® • "(" -> ? "operator" "(" ® •
case 4: // ? "operator" ® • "[" -> ? "operator" "[" ® •
fToken = aToken;
aParser->TopItem(aToken);
aParser->Shift(this);
break;
case 5: // ? "operator" "(" ® • ")" -> • kSLex_Id
case 6: // ? "operator" "[" ® • "]" -> • kSLex_Id
SexChange(kSLex_Id);
aParser->Reduce(this, 3);
break;
case 7: // ? "operator" "(" ® • ??? -> ? • kSLex_ParsedId "(" ???
case 8: // ? "operator" "[" ® • ??? -> ? • kSLex_ParsedId "[" ???
{
Syntactic* open = aParser->Pick(1);
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aParser->Drop(3);
return (aParser->Parse(&gLexOperator) && aParser->Parse(open) && aParser->Parse(aToken));
}
case 9: // ? "operator" ® • ??? -> ? • kSLex_ParsedId ???
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
aParser->Drop(2);
return (aParser->Parse(&gLexOperator) && aParser->Parse(aToken));
default:
if (aToken->IsSeparator())
{
aFormat->Display(aToken);
return (true);
}
return (false);
}
return (true);
}
/*µ kSPrs_NewLine
** If the newline is followed by an opening curly or the keyword "else", then
** this newline can be ignored. Other tokens require that the newline be passed
** along and then the new token be handled.
*/
//µ PrsNewLine::Accept
#pragma segment ParserActions
Boolean PrsNewLine::Accept(Syntactic *aToken, Parser *aParser)
{
aParser->Drop(1);
switch (aToken->Type()) {
case kSLex_LCurly:
case kSLex_Else:
return (aParser->Parse(aToken));
default:
aParser->Parse(this);
return (aParser->Parse(aToken));
}
return (true);
}
//µ PrsNewLineIf::Accept
Boolean PrsNewLineIf::Accept(Syntactic *aToken, Parser *aParser)
{
switch (aToken->Type()) {
case kSLex_If:
aParser->Drop(1);
return (aParser->Parse(aToken));
default:
return (PrsNewLine::Accept(aToken, aParser));
}
return (true);
}
/*
** Display methods
*/
//µ SyntacticPrs::Display
#pragma segment ParserActions
Boolean SyntacticPrs::Display(Formatting *)
{
// Doesn't display
return (false);
}
//µ PrsPlaceHolder::Display
#pragma segment ParserActions
Boolean PrsPlaceHolder::Display(Formatting *aFormat)
{
// Display the string. Return true if there was a string to display
aFormat->Print(fString);
return (fString && *fString);
}
//µ PrsId::Display
#pragma segment ParserActions
Boolean PrsId::Display(Formatting *aFormat)
{
aFormat->Display(fClassName);
aFormat->Display(fClassOp);
aFormat->Display(fMemberName);
// Return false. The above aFormat->Display() call is what was important,
// not this placeholder
return (false);
}
//µ PrsDestructor::Display
#pragma segment ParserActions
Boolean PrsDestructor::Display(Formatting *aFormat)
{
aFormat->Display(&gLexBNot);
aFormat->Display(fMemberName);
// Return false. The above aFormat->Display() call is what was important,
// not this placeholder
return (false);
}
//µ PrsAsId::Display
#pragma segment ParserActions
Boolean PrsAsId::Display(Formatting *aFormat)
{
// Hand it off to the token itself
aFormat->Display(fToken);
// Return false. The above aFormat->Display() call is what was important,
// not this placeholder
return (false);
}
/*
** Display the contents of the "operator"
*/
//µ PrsDeclOperator::Display
#pragma segment ParserActions
Boolean PrsDeclOperator::Display(Formatting *aFormat)
{
short aType = fToken->Type();
aFormat->Display(&gLexOperator);
switch (aType) {
case kSLex_Id:
case kSLex_ParsedId:
aFormat->Name();
break;
}
aFormat->Display(fToken);
switch (aType) {
case kSLex_LParen:
aFormat->Display(&gLexRParen);
break;
case kSLex_LBrace:
aFormat->Display(&gLexRBrace);
break;
}
// Return false, as this PrsDeclOperator token should not affect the
// display: what was last passed to aFormat->Display() should affect
// the display.
return (false);
}
//µ PrsNewLine::IsSeparator
#pragma segment ParserActions
Boolean PrsNewLine::IsSeparator() const
{
return (true);
}
//µ PrsNewLine::Display
#pragma segment ParserActions
Boolean PrsNewLine::Display(Formatting *aFormat)
{
aFormat->NewLine();
return (true);
}
//µ SyntacticPrs::IsSeparator
#pragma segment ParserActions
Boolean SyntacticPrs::IsSeparator() const
{
return (false);
}
//µ SyntacticPrs::SaveCopy
#pragma segment ParserActions
const Syntactic *SyntacticPrs::SaveCopy() const
{
return (this);
}
//µ PrsPlaceHolder::Accept
#pragma segment ParserActions
Boolean PrsPlaceHolder::Accept(Syntactic *, Parser *)
{
return (false);
}